/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace AK { template class Queue { public: Queue() = default; ~Queue() = default; size_t size() const { return m_size; } bool is_empty() const { return m_size == 0; } template void enqueue(U&& value) { if (m_segments.is_empty() || m_segments.last()->size() >= segment_size) m_segments.append(make>()); m_segments.last()->append(forward(value)); ++m_size; } T dequeue() { VERIFY(!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 { VERIFY(!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; size_t m_index_into_first { 0 }; size_t m_size { 0 }; }; } using AK::Queue;