export module Core.Queue; export import Core.New; import Core.AlignedData; import Core.ToString; import Core.Meta; import Core.Utility; import Core.Assert; export namespace Core { template class Queue final { AlignedType data[N]; size_t writeIndex = 0; size_t readIndex = 0; size_t values = 0; public: Queue() = default; Queue(const Queue& other) { copy(other); } Queue(Queue&& other) noexcept { move(Core::move(other)); other.clear(); } ~Queue() { clear(); } Queue& operator=(const Queue& other) { if(&other != this) { clear(); copy(other); } return *this; } Queue& operator=(Queue&& other) noexcept { if(&other != this) { clear(); move(Core::move(other)); other.clear(); } return *this; } template T* put(Args&&... args) { if(getLength() >= N) { return nullptr; } T* t = new(data + writeIndex) T(Core::forward(args)...); writeIndex = (writeIndex + 1) % N; values++; return t; } template Queue& add(Args&&... args) { put(Core::forward(args)...); return *this; } T& operator[](size_t index) { return reinterpret_cast(data)[(index + readIndex) % N]; } const T& operator[](size_t index) const { return reinterpret_cast(data)[(index + readIndex) % N]; } size_t getLength() const { return values; } bool canRemove() const { return getLength() > 0; } void clear() { for(size_t i = 0; i < getLength(); i++) { (*this)[i].~T(); } writeIndex = 0; readIndex = 0; values = 0; } void remove() { assert(canRemove()); values--; (*this)[0].~T(); readIndex = (readIndex + 1) % N; } size_t toString(char* s, size_t n) const { size_t total = 0; addString("[", s, n, total); size_t end = getLength(); if(end > 0) { end--; for(size_t i = 0; i < end; i++) { addString((*this)[i], s, n, total); addString(", ", s, n, total); } addString((*this)[end], s, n, total); } addString("]", s, n, total); return total; } private: void copy(const Queue& other) { for(size_t i = 0; i < other.getLength(); i++) { add(other[i]); } } void move(Queue&& other) { for(size_t i = 0; i < other.getLength(); i++) { add(Core::move(other[i])); } } }; }