#ifndef CORE_ARRAYLIST_HPP #define CORE_ARRAYLIST_HPP #include "core/utils/AlignedData.hpp" #include "core/utils/ArrayString.hpp" namespace Core { template class ArrayList final { static_assert(N > 0, "ArrayList size must be positive"); AlignedType data[static_cast(N)]; i64 length; public: ArrayList() : length(0) { } ArrayList(const ArrayList& other) : ArrayList() { copy(other); } ArrayList(ArrayList&& other) : ArrayList() { move(Core::move(other)); other.clear(); } ~ArrayList() { clear(); } ArrayList& operator=(const ArrayList& other) { if(&other != this) { clear(); copy(other); } return *this; } ArrayList& operator=(ArrayList&& other) { if(&other != this) { clear(); move(Core::move(other)); other.clear(); } return *this; } T* begin() { return reinterpret_cast(data); } T* end() { return begin() + length; } const T* begin() const { return reinterpret_cast(data); } const T* end() const { return begin() + length; } template check_return Error put(T*& t, Args&&... args) { if(length >= N) { return Error::CAPACITY_REACHED; } t = new(begin() + length++) T(Core::forward(args)...); return Error::NONE; } template check_return Error add(Args&&... args) { T* t = nullptr; return put(t, Core::forward(args)...); } T& operator[](i64 index) { return begin()[index]; } const T& operator[](i64 index) const { return begin()[index]; } i64 getLength() const { return length; } void clear() { for(i64 i = 0; i < length; i++) { begin()[i].~T(); } length = 0; } check_return Error removeBySwap(i64 index) { if(index < 0 || index >= length) { return Error::INVALID_INDEX; } length--; if(index != length) { begin()[index] = Core::move(begin()[length]); } begin()[length].~T(); return Error::NONE; } check_return Error removeLast() { return removeBySwap(length - 1); } template check_return Error toString(String& s) const { return Core::toString(s, *this); } private: void copy(const ArrayList& other) { for(i64 i = 0; i < other.length; i++) { (void)add(other[i]); } } void move(ArrayList&& other) { for(i64 i = 0; i < other.length; i++) { (void)add(Core::move(other[i])); } } }; } #endif