#pragma once #if !defined(MIJIN_CONTAINER_INLINE_ARRAY_HPP_INCLUDED) #define MIJIN_CONTAINER_INLINE_ARRAY_HPP_INCLUDED 1 #include "./boxed_object.hpp" namespace mijin { // // public defines // // // public constants // // // public types // template class InlineArray { public: using element_type = T; using value_type = std::remove_cv_t; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using iterator = BoxedObjectIterator; using const_iterator = BoxedObjectIterator; private: BoxedObject elements_[maxSize]; // NOLINT(modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) size_type size_ = 0; public: InlineArray() = default; InlineArray(const InlineArray& other); InlineArray(InlineArray&& other) noexcept; ~InlineArray(); reference operator[](size_type index); const_reference operator[](size_type index) const; [[nodiscard]] iterator begin() { return BoxedObjectIterator(&elements_[0], &elements_[0], &elements_[size_]); } [[nodiscard]] const_iterator begin() const { return BoxedObjectIterator(&elements_[0], &elements_[0], &elements_[size_]); } [[nodiscard]] const_iterator cbegin() const { return BoxedObjectIterator(&elements_[0], &elements_[0], &elements_[size_]); } [[nodiscard]] iterator end() { return BoxedObjectIterator(&elements_[size_], &elements_[0], &elements_[size_]); } [[nodiscard]] const_iterator end() const { return BoxedObjectIterator(&elements_[size_], &elements_[0], &elements_[size_]); } [[nodiscard]] const_iterator cend() const { return BoxedObjectIterator(&elements_[size_], &elements_[0], &elements_[size_]); } [[nodiscard]] constexpr size_type size() const { return size_; } [[nodiscard]] constexpr size_type capacity() const { return maxSize; } [[nodiscard]] constexpr bool empty() const { return size_ == 0; } [[nodiscard]] constexpr reference at(size_type index) { MIJIN_ASSERT(index < size_, "InlineArray::at() attempt to access out-of-bounds index."); return elements_[index].get(); } [[nodiscard]] constexpr const_reference at(size_type index) const { MIJIN_ASSERT(index < size_, "InlineArray::at() attempt to access out-of-bounds index."); return elements_[index].get(); } void resize(size_type newSize); void clear() { resize(0); } }; // // public functions // template InlineArray::InlineArray(const InlineArray& other) : size_(other.size_) { for (size_type idx = 0; idx < size_; ++idx) { other.elements_[idx].copyTo(elements_[idx]); } } template InlineArray::InlineArray(InlineArray&& other) noexcept : size_(other.size_) { for (size_type idx = 0; idx < size_; ++idx) { other.elements_[idx].moveTo(elements_[idx]); } other.size_ = 0; } template InlineArray::~InlineArray() { for (std::size_t idx = 0; idx < size_; ++idx) { elements_[idx].destroy(); } } template auto InlineArray::operator[](size_type index) -> reference { return at(index); } template auto InlineArray::operator[](size_type index) const -> const_reference { return at(index); } template void InlineArray::resize(size_type newSize) { MIJIN_ASSERT(newSize <= numElements, "InlineArray::resize(): Attempt to resize beyond maximum size."); if (newSize < size_) { for (size_type idx = newSize; idx < size_; ++idx) { elements_[idx].destroy(); } } else { for (size_type idx = size_; idx < newSize; ++idx) { elements_[idx].construct(); } } size_ = newSize; } } // namespace mijin #endif // !defined(MIJIN_CONTAINER_INLINE_ARRAY_HPP_INCLUDED)