From c8b7173aa8a08fe51d6e9901a5222a75730cf95d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 22 Oct 2018 22:46:02 +0200 Subject: [PATCH] Add a CircularQueue template class to AK. --- AK/CircularQueue.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++ AK/StringImpl.cpp | 5 +++-- AK/test.cpp | 37 ++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 AK/CircularQueue.h diff --git a/AK/CircularQueue.h b/AK/CircularQueue.h new file mode 100644 index 00000000000..45942a114de --- /dev/null +++ b/AK/CircularQueue.h @@ -0,0 +1,56 @@ +#pragma once + +#include "Types.h" +#include "kstdio.h" + +namespace AK { + +template +class CircularQueue { +public: + CircularQueue() + { + for (size_t i = 0; i < capacity; ++i) + m_elements[i] = T(); + } + + bool isEmpty() const { return !m_size; } + size_t size() const { return m_size; } + + void dump() const + { + kprintf("CircularQueue<%zu>:\n", capacity); + kprintf(" size: %zu\n", m_size); + for (size_t i = 0; i < capacity; ++i) { + kprintf(" [%zu] %d %c\n", i, m_elements[i], i == m_head ? '*' : ' '); + } + } + + void enqueue(const T& t) + { + m_elements[(m_head + m_size) % capacity] = t; + if (m_size == capacity) + m_head = (m_head + 1) % capacity; + else + ++m_size; + } + + T dequeue() + { + ASSERT(!isEmpty()); + T value = m_elements[m_head]; + m_head = (m_head + 1) % capacity; + --m_size; + return value; + } + +private: + T m_elements[capacity]; + size_t m_size { 0 }; + size_t m_head { 0 }; +}; + +} + +using AK::CircularQueue; + diff --git a/AK/StringImpl.cpp b/AK/StringImpl.cpp index be83cfc4192..c89d080b136 100644 --- a/AK/StringImpl.cpp +++ b/AK/StringImpl.cpp @@ -8,12 +8,13 @@ static StringImpl* s_theEmptyStringImpl = nullptr; void StringImpl::initializeGlobals() { - s_theEmptyStringImpl = new StringImpl(ConstructTheEmptyStringImpl);; + s_theEmptyStringImpl = nullptr; } StringImpl& StringImpl::theEmptyStringImpl() { - ASSERT(s_theEmptyStringImpl); + if (!s_theEmptyStringImpl) + s_theEmptyStringImpl = new StringImpl(ConstructTheEmptyStringImpl);; return *s_theEmptyStringImpl; } diff --git a/AK/test.cpp b/AK/test.cpp index 0cb2b89de7f..d017990d001 100644 --- a/AK/test.cpp +++ b/AK/test.cpp @@ -9,11 +9,48 @@ #include "Buffer.h" #include "Weakable.h" #include "WeakPtr.h" +#include "CircularQueue.h" static void testWeakPtr(); int main(int, char**) { + StringImpl::initializeGlobals(); + { + CircularQueue queue; + queue.dump(); + queue.enqueue(1); + queue.dump(); + queue.enqueue(2); + queue.dump(); + queue.enqueue(3); + queue.dump(); + queue.enqueue(4); + ASSERT(!queue.isEmpty()); + ASSERT(queue.size() == 4); + ASSERT(queue.dequeue() == 1); + queue.dump(); + ASSERT(queue.dequeue() == 2); + queue.dump(); + ASSERT(queue.dequeue() == 3); + queue.dump(); + ASSERT(queue.dequeue() == 4); + queue.dump(); + ASSERT(queue.isEmpty()); + queue.enqueue(1); + queue.enqueue(2); + queue.enqueue(3); + queue.enqueue(4); + queue.enqueue(5); + queue.enqueue(6); + queue.enqueue(7); + ASSERT(queue.dequeue() == 4); + ASSERT(queue.dequeue() == 5); + ASSERT(queue.dequeue() == 6); + ASSERT(queue.dequeue() == 7); + ASSERT(queue.isEmpty()); + } + { String path = "/////abc/def////g/h/i//"; auto parts = path.split('/');