export module Core.Queue; export import Core.New; export import Core.ToString; import Core.AlignedData; 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() noexcept = default; Queue(const Queue& other) noexcept { copy(other); } Queue(Queue&& other) noexcept { move(Core::move(other)); other.clear(); } ~Queue() noexcept { clear(); } Queue& operator=(const Queue& other) noexcept { 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) noexcept { if(getLength() >= N) { return nullptr; } static_assert(noexcept(new(data + writeIndex) T(Core::forward(args)...))); T* t = new(data + writeIndex) T(Core::forward(args)...); writeIndex = (writeIndex + 1) % N; values++; return t; } template Queue& add(Args&&... args) noexcept { put(Core::forward(args)...); return *this; } T& operator[](size_t index) noexcept { return reinterpret_cast(data)[(index + readIndex) % N]; } const T& operator[](size_t index) const noexcept { return reinterpret_cast(data)[(index + readIndex) % N]; } size_t getLength() const noexcept { return values; } bool canRemove() const noexcept { return getLength() > 0; } void clear() noexcept { for(size_t i = 0; i < getLength(); i++) { (*this)[i].~T(); } writeIndex = 0; readIndex = 0; values = 0; } void remove() noexcept { assert(canRemove()); values--; (*this)[0].~T(); readIndex = (readIndex + 1) % N; } size_t toString(StringBase& b) const noexcept { size_t oldtotal = b.getTotal(); b.add("["); size_t end = getLength(); if(end > 0) { end--; for(size_t i = 0; i < end; i++) { b.add((*this)[i]); b.add(", "); } b.add((*this)[end]); } b.add("]"); return b.getTotal() - oldtotal; } private: void copy(const Queue& other) noexcept { for(size_t i = 0; i < other.getLength(); i++) { add(other[i]); } } void move(Queue&& other) noexcept { for(size_t i = 0; i < other.getLength(); i++) { add(Core::move(other[i])); } } }; }