| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- 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<Moveable T, size_t N>
- class Queue final {
- AlignedType<T> 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<typename... Args>
- T* put(Args&&... args) noexcept {
- if(getLength() >= N) {
- return nullptr;
- }
- static_assert(noexcept(new(data + writeIndex)
- T(Core::forward<Args>(args)...)));
- T* t = new(data + writeIndex) T(Core::forward<Args>(args)...);
- writeIndex = (writeIndex + 1) % N;
- values++;
- return t;
- }
- template<typename... Args>
- Queue& add(Args&&... args) noexcept {
- put(Core::forward<Args>(args)...);
- return *this;
- }
- T& operator[](size_t index) noexcept {
- return reinterpret_cast<T*>(data)[(index + readIndex) % N];
- }
- const T& operator[](size_t index) const noexcept {
- return reinterpret_cast<const T*>(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]));
- }
- }
- };
- }
|