#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); FixedCapacityContainer &operator=(const std::vector &other); bool operator==(const std::vector &other) const; bool operator!=(const std::vector &other) const; template bool operator==(const FixedCapacityContainer &other) const; template bool operator!=(const FixedCapacityContainer &other) const; T &operator[](size_t i) { return data_[i]; } const T &operator[](size_t i) const { return data_[i]; } size_t size() const { return size_; } bool empty() const{ return size_ == 0;} size_t capacity() const { return Capacity; } void push_back(const T &value); void resize(size_t new_size); void erase(T *ptr); T &front() { return data_.front(); } T &back() { return data_[size_ - 1]; } const T &front() const { return data_.front(); } const T &back() const { return data_[size_ - 1]; } // iterators T *begin() { return &data_[0]; } T *end() { return &data_[size_]; } const T *cbegin() const { return &data_[0]; } const T *cend() const { 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) { size_ = v.size(); std::copy(v.begin(), v.end(), 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 { 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 { return !(*this == other); } template template bool FixedCapacityContainer:: operator==(const FixedCapacityContainer &other) const { 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 { 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 T *begin(FixedCapacityContainer &container) { return container.begin(); } template T *end(FixedCapacityContainer &container) { return container.end(); } template bool operator==(const std::vector &vec, const FixedCapacityContainer &fixed_container) { return fixed_container == vec; } template bool operator!=(const std::vector &vec, const FixedCapacityContainer &fixed_container) { return fixed_container != vec; } } // namespace sls