From 2a30a020c13e462cba6e197f92a3171d79b12ba2 Mon Sep 17 00:00:00 2001 From: howar6hill Date: Mon, 2 Mar 2020 16:50:43 +0800 Subject: [PATCH] AK: Add enqueue_begin() for the CircularDeque class (#1320) Also add tests for CircularDeque. --- AK/CircularDeque.h | 18 ++++++++ AK/Tests/TestCircularDeque.cpp | 84 ++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 AK/Tests/TestCircularDeque.cpp diff --git a/AK/CircularDeque.h b/AK/CircularDeque.h index 445abe46aa..06cd66a528 100644 --- a/AK/CircularDeque.h +++ b/AK/CircularDeque.h @@ -35,6 +35,24 @@ namespace AK { template class CircularDeque : public CircularQueue { public: + void enqueue_begin(T&& value) + { + const auto new_head = (this->m_head - 1 + Capacity) % Capacity; + auto& slot = this->elements()[new_head]; + if (this->m_size == Capacity) + slot.~T(); + else + ++this->m_size; + + new (&slot) T(move(value)); + this->m_head = new_head; + } + + void enqueue_begin(const T& value) + { + enqueue_begin(T(value)); + } + T dequeue_end() { ASSERT(!this->is_empty()); diff --git a/AK/Tests/TestCircularDeque.cpp b/AK/Tests/TestCircularDeque.cpp new file mode 100644 index 0000000000..24d180b965 --- /dev/null +++ b/AK/Tests/TestCircularDeque.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018-2020, Fei Wu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +TEST_CASE(enqueue_begin) +{ + CircularDeque ints; + + ints.enqueue_begin(0); + EXPECT_EQ(ints.size(), 1); + EXPECT_EQ(ints.first(), 0); + + ints.enqueue_begin(1); + EXPECT_EQ(ints.size(), 2); + EXPECT_EQ(ints.first(), 1); + EXPECT_EQ(ints.last(), 0); + + ints.enqueue_begin(2); + EXPECT_EQ(ints.size(), 3); + EXPECT_EQ(ints.first(), 2); + EXPECT_EQ(ints.last(), 0); + + ints.enqueue_begin(3); + EXPECT_EQ(ints.size(), 3); + EXPECT_EQ(ints.first(), 3); + EXPECT_EQ(ints.at(1), 2); + EXPECT_EQ(ints.last(), 1); +} + +TEST_CASE(enqueue_begin_being_moved_from) +{ + CircularDeque strings; + + String str{"test"}; + strings.enqueue_begin(move(str)); + EXPECT(str.is_null()); +} + +TEST_CASE(deque_end) +{ + CircularDeque ints; + ints.enqueue(0); + ints.enqueue(1); + ints.enqueue(2); + EXPECT_EQ(ints.size(), 3); + + EXPECT_EQ(ints.dequeue_end(), 2); + EXPECT_EQ(ints.size(), 2); + + EXPECT_EQ(ints.dequeue_end(), 1); + EXPECT_EQ(ints.size(), 1); + + EXPECT_EQ(ints.dequeue_end(), 0); + EXPECT(ints.is_empty()); +} + +TEST_MAIN(CircularDeque)