diff --git a/AK/Queue.h b/AK/Queue.h new file mode 100644 index 00000000000..b3ae8f024ad --- /dev/null +++ b/AK/Queue.h @@ -0,0 +1,49 @@ +#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; + } + + 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; + } + +private: + static const int segment_size = 1000; + + SinglyLinkedList>> m_segments; + int m_index_into_first { 0 }; + int m_size { 0 }; +}; + +} + +using AK::Queue; + diff --git a/AK/SinglyLinkedList.h b/AK/SinglyLinkedList.h index c14fe97b452..34e837c465d 100644 --- a/AK/SinglyLinkedList.h +++ b/AK/SinglyLinkedList.h @@ -9,7 +9,7 @@ class SinglyLinkedList { private: struct Node { explicit Node(T&& v) - : value(v) + : value(move(v)) { } T value; @@ -66,7 +66,7 @@ public: { ASSERT(m_head); auto* prev_head = m_head; - T value = first(); + T value = move(first()); if (m_tail == m_head) m_tail = nullptr; m_head = m_head->next; diff --git a/AK/Tests/Makefile b/AK/Tests/Makefile index 5cde4d3fc78..dd7fc4a8e87 100644 --- a/AK/Tests/Makefile +++ b/AK/Tests/Makefile @@ -1,9 +1,12 @@ -all: TestString +all: TestString TestQueue CXXFLAGS = -std=c++17 -Wall -Wextra TestString: TestString.cpp ../String.cpp ../StringImpl.cpp ../StringBuilder.cpp ../StringView.cpp TestHelpers.h $(CXX) $(CXXFLAGS) -I../ -I../../ -o $@ TestString.cpp ../String.cpp ../StringImpl.cpp ../StringBuilder.cpp ../StringView.cpp +TestQueue: TestQueue.cpp ../String.cpp ../StringImpl.cpp ../StringBuilder.cpp ../StringView.cpp TestHelpers.h + $(CXX) $(CXXFLAGS) -I../ -I../../ -o $@ TestQueue.cpp ../String.cpp ../StringImpl.cpp ../StringBuilder.cpp ../StringView.cpp + clean: - rm -f TestString + rm -f TestString TestQueue diff --git a/AK/Tests/TestQueue.cpp b/AK/Tests/TestQueue.cpp new file mode 100644 index 00000000000..b5496c052a2 --- /dev/null +++ b/AK/Tests/TestQueue.cpp @@ -0,0 +1,31 @@ +#include "TestHelpers.h" +#include +#include + +int main() +{ + EXPECT(Queue().is_empty()); + EXPECT(Queue().size() == 0); + + Queue ints; + ints.enqueue(1); + ints.enqueue(2); + ints.enqueue(3); + EXPECT(ints.size() == 3); + EXPECT(ints.dequeue() == 1); + EXPECT(ints.size() == 2); + EXPECT(ints.dequeue() == 2); + EXPECT(ints.size() == 1); + EXPECT(ints.dequeue() == 3); + EXPECT(ints.size() == 0); + + Queue strings; + strings.enqueue("ABC"); + strings.enqueue("DEF"); + EXPECT(strings.size() == 2); + EXPECT(strings.dequeue() == "ABC"); + EXPECT(strings.dequeue() == "DEF"); + EXPECT(strings.is_empty()); + + return 0; +}