export module Core.ArrayList; export import Core.New; import Core.AlignedData; import Core.Meta; import Core.Types; import Core.Assert; export namespace Core { template class ArrayList final { AlignedType data[N]; size_t length; public: ArrayList() noexcept : length(0) { } ArrayList(const ArrayList& other) noexcept : ArrayList() { copy(other); } ArrayList(ArrayList&& other) noexcept : ArrayList() { move(Core::move(other)); other.clear(); } ~ArrayList() noexcept { clear(); } ArrayList& operator=(const ArrayList& other) noexcept { if(&other != this) { clear(); copy(other); } return *this; } ArrayList& operator=(ArrayList&& other) noexcept { if(&other != this) { clear(); move(Core::move(other)); other.clear(); } return *this; } T* begin() noexcept { return reinterpret_cast(data); } T* end() noexcept { return begin() + length; } const T* begin() const noexcept { return reinterpret_cast(data); } const T* end() const noexcept { return begin() + length; } template T* put(Args&&... args) noexcept { if(length < N) { static_assert( noexcept(new(begin()) T(Core::forward(args)...))); return new(begin() + length++) T(Core::forward(args)...); } return nullptr; } template ArrayList& add(Args&&... args) noexcept { put(Core::forward(args)...); return *this; } template T* putAt(size_t t, Args&&... args) noexcept { if(length >= N) { return nullptr; } else if(t >= length) { return put(Core::forward(args)...); } put(Core::move(begin()[length - 1])); for(size_t i = length - 2; i > t; i--) { (*this)[i] = Core::move((*this)[i - 1]); } (*this)[t] = Core::move(T(Core::forward(args)...)); return begin() + t; } template ArrayList& addAt(size_t index, Args&&... args) noexcept { putAt(index, Core::forward(args)...); return *this; } T& operator[](size_t index) noexcept { return begin()[index]; } const T& operator[](size_t index) const noexcept { return begin()[index]; } T& getLast() noexcept { assert(length > 0); return begin()[length - 1]; } const T& getLast() const noexcept { assert(length > 0); return begin()[length - 1]; } size_t getLength() const noexcept { return length; } consteval size_t getCapacity() const noexcept { return N; } void clear() noexcept { for(size_t i = 0; i < length; i++) { begin()[i].~T(); } length = 0; } void removeBySwap(size_t index) noexcept { assert(index < length); length--; if(index != length) { begin()[index] = Core::move(begin()[length]); } begin()[length].~T(); } void remove(size_t index) noexcept { assert(index < length); length--; T* currentT = begin() + index; T* endT = end(); while(currentT != endT) { T* nextT = currentT + 1; *currentT = Core::move(*nextT); currentT = nextT; } endT->~T(); } void removeLast() noexcept { removeBySwap(length - 1); } private: void copy(const ArrayList& other) noexcept { for(size_t i = 0; i < other.length; i++) { add(other[i]); } } void move(ArrayList&& other) noexcept { for(size_t i = 0; i < other.length; i++) { add(Core::move(other[i])); } } }; }