#pragma once #include #include #include #include namespace sls { template class FixedCapacityContainer { public: FixedCapacityContainer() = default; explicit FixedCapacityContainer(std::initializer_list l); explicit FixedCapacityContainer(const std::vector &v); template explicit FixedCapacityContainer( const FixedCapacityContainer &other) noexcept; FixedCapacityContainer &operator=(const std::vector &other); bool operator==(const std::vector &other) const noexcept; bool operator!=(const std::vector &other) const noexcept; operator std::vector(){return std::vector(begin(), end());} template bool operator==(const FixedCapacityContainer &other) const noexcept; template bool operator!=(const FixedCapacityContainer &other) const noexcept; T &operator[](size_t i) { return data_[i]; } const T &operator[](size_t i) const { return data_[i]; } constexpr size_t size() const noexcept { return size_; } bool empty() const noexcept { return size_ == 0; } constexpr size_t capacity() const noexcept { return Capacity; } void push_back(const T &value); void resize(size_t new_size); void erase(T *ptr); T &front() noexcept { return data_.front(); } T &back() noexcept { return data_[size_ - 1]; } constexpr const T &front() const noexcept { return data_.front(); } constexpr const T &back() const noexcept { return data_[size_ - 1]; } // iterators T *begin() noexcept { return &data_[0]; } T *end() noexcept { return &data_[size_]; } const T *cbegin() const noexcept { return &data_[0]; } const T *cend() const noexcept { return &data_[size_]; } private: size_t size_{0}; std::array data_; } __attribute__((packed)); /* Member functions */ template FixedCapacityContainer::FixedCapacityContainer( std::initializer_list l) { size_ = l.size(); std::copy(l.begin(), l.end(), data_.begin()); } template FixedCapacityContainer::FixedCapacityContainer( const std::vector &v) { if (v.size() > Capacity) { throw std::runtime_error( "Capacity needs to be same size or larger than vector"); } size_ = v.size(); std::copy(v.begin(), v.end(), data_.begin()); } template template FixedCapacityContainer::FixedCapacityContainer( const FixedCapacityContainer &other) noexcept { static_assert(Capacity >= OtherCapacity, "Container needs to be same size or larger"); size_ = other.size(); std::copy(other.cbegin(), other.cend(), data_.begin()); } template void FixedCapacityContainer::push_back(const T &value) { if (size_ == Capacity) { throw std::runtime_error("Container is full"); } else { data_[size_] = value; ++size_; } } template void FixedCapacityContainer::resize(size_t new_size) { if (new_size > Capacity) { throw std::runtime_error("Cannot resize beyond capacity"); } else { size_ = new_size; } } template FixedCapacityContainer &FixedCapacityContainer:: operator=(const std::vector &other) { std::copy(other.begin(), other.end(), data_.begin()); size_ = other.size(); return *this; } template bool FixedCapacityContainer:: operator==(const std::vector &other) const noexcept { if (size_ != other.size()) { return false; } else { for (size_t i = 0; i != size_; ++i) { if (data_[i] != other[i]) { return false; } } } return true; } template bool FixedCapacityContainer:: operator!=(const std::vector &other) const noexcept { return !(*this == other); } template template bool FixedCapacityContainer:: operator==(const FixedCapacityContainer &other) const noexcept { if (size_ != other.size()) { return false; } else { for (size_t i = 0; i != size_; ++i) { if (data_[i] != other[i]) { return false; } } } return true; } template template bool FixedCapacityContainer:: operator!=(const FixedCapacityContainer &other) const noexcept { return !(*this == other); } template void FixedCapacityContainer::erase(T *ptr) { if (ptr >= begin() && ptr < end()) { size_ = static_cast(ptr - begin()); } else { throw std::runtime_error("tried to erase with a ptr outside obj"); } } /* Free function concerning FixedCapacityContainer */ template constexpr T *begin(FixedCapacityContainer &container) noexcept { return container.begin(); } template constexpr T *end(FixedCapacityContainer &container) noexcept { return container.end(); } template bool operator==( const std::vector &vec, const FixedCapacityContainer &fixed_container) noexcept { return fixed_container == vec; } template bool operator!=( const std::vector &vec, const FixedCapacityContainer &fixed_container) noexcept { return fixed_container != vec; } } // namespace sls