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