#pragma once #include #include #include namespace AK { template class Queue { public: Queue() { } ~Queue() { } int size() const { return m_size; } bool is_empty() const { return m_size == 0; } void enqueue(T&& value) { if (m_segments.is_empty() || m_segments.last()->size() >= segment_size) m_segments.append(make>()); m_segments.last()->append(move(value)); ++m_size; } void enqueue(const T& value) { enqueue(T(value)); } T dequeue() { ASSERT(!is_empty()); auto value = move((*m_segments.first())[m_index_into_first++]); if (m_index_into_first == segment_size) { m_segments.take_first(); m_index_into_first = 0; } --m_size; return value; } const T& head() const { ASSERT(!is_empty()); return (*m_segments.first())[m_index_into_first]; } void clear() { m_segments.clear(); m_index_into_first = 0; m_size = 0; } private: SinglyLinkedList>> m_segments; int m_index_into_first { 0 }; int m_size { 0 }; }; } using AK::Queue;