From 0f48bb806047abe2867ca30ee784a81a3e4c4e17 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Sat, 16 Dec 2023 15:53:02 -0500 Subject: [PATCH] stacky --- include/blt/std/queue.h | 142 ++++++++++++++++++++++++------ tests/include/blt_tests.h | 40 +++++++++ tests/src/datastructure_tests.cpp | 108 +++++++++++++++++++++++ tests/src/main.cpp | 9 +- 4 files changed, 267 insertions(+), 32 deletions(-) create mode 100644 tests/include/blt_tests.h create mode 100644 tests/src/datastructure_tests.cpp diff --git a/include/blt/std/queue.h b/include/blt/std/queue.h index 69c2734..5cb27c2 100755 --- a/include/blt/std/queue.h +++ b/include/blt/std/queue.h @@ -10,14 +10,16 @@ /** * */ -namespace blt { +namespace blt +{ /** * Standard array backed first in first out queue * @tparam T type stored in the queue */ template - class flat_stack { + class flat_stack + { private: int m_size = 16; int m_insertIndex = 0; @@ -28,7 +30,8 @@ namespace blt { * and deletes the old array from memory. * @param newSize new size of the internal array */ - void expand() { + void expand() + { int new_size = m_size * 2; auto tempData = new T[new_size]; for (int i = 0; i < m_insertIndex; i++) @@ -40,8 +43,10 @@ namespace blt { public: - void push(const T& t) { - if (m_insertIndex >= m_size) { + void push(const T& t) + { + if (m_insertIndex >= m_size) + { expand(); } m_data[m_insertIndex++] = t; @@ -51,25 +56,30 @@ namespace blt { * Warning does not contain runtime error checking! * @return the element at the "front" of the queue. */ - [[nodiscard]] const T& top() const { + [[nodiscard]] const T& top() const + { return m_data[m_insertIndex - 1]; } - void pop() { + void pop() + { if (empty()) return; m_insertIndex--; } - - [[nodiscard]] inline bool empty() const { + + [[nodiscard]] inline bool empty() const + { return m_insertIndex <= 0; } - - [[nodiscard]] inline int size() const { + + [[nodiscard]] inline int size() const + { return m_insertIndex; } - ~flat_stack() { + ~flat_stack() + { delete[](m_data); } }; @@ -79,16 +89,19 @@ namespace blt { * @tparam T type stored in the queue */ template - class flat_queue { + class flat_queue + { private: int m_size = 16; int m_headIndex = 0; int m_insertIndex = 0; T* m_data; + /** * Expands the internal array to allow for more storage of elements */ - void expand() { + void expand() + { int new_size = m_size * 2; int removed_size = m_size - m_headIndex; auto tempData = new T[new_size]; @@ -103,12 +116,15 @@ namespace blt { } public: - flat_queue(): m_data(new T[m_size]) { + flat_queue(): m_data(new T[m_size]) + { } - - inline void push(const T& t) { - if (m_insertIndex+1 >= m_size) { + + inline void push(const T& t) + { + if (m_insertIndex + 1 >= m_size) + { expand(); } m_data[m_insertIndex++] = t; @@ -118,36 +134,106 @@ namespace blt { * Warning does not contain runtime error checking! * @return the element at the "front" of the queue. */ - [[nodiscard]] const T& front() const { + [[nodiscard]] const T& front() const + { return m_data[m_headIndex]; } - - inline void pop() { + + [[nodiscard]] T& front() + { + return m_data[m_headIndex]; + } + + inline void pop() + { if (empty()) return; m_headIndex++; } - [[nodiscard]] inline bool empty() const { + [[nodiscard]] inline bool empty() const + { return m_headIndex >= m_size; } - [[nodiscard]] inline int size() const { + [[nodiscard]] inline int size() const + { return m_insertIndex - m_headIndex; } - - inline T* begin(){ + + inline T* begin() + { return m_data[m_headIndex]; } - - inline T* end(){ + + inline T* end() + { return m_data[m_insertIndex]; } - ~flat_queue() { + ~flat_queue() + { delete[](m_data); } }; + + template + class linked_stack + { + private: + struct node + { + T t; + node* next; + + node(const T& t, node* node): t(t), next(node) + {} + + node(T&& t, node* node): t(std::move(t)), next(node) + {} + }; + + node* head = nullptr; + public: + inline void push(const T& t) + { + head = new node(t, head); + } + + inline void push(T&& t) + { + head = new node(std::move(t), head); + } + + inline T& top() + { + return head->t; + } + + + inline const T& top() const + { + return head->t; + } + + inline void pop() + { + auto* h = head; + head = head->next; + delete h; + } + + ~linked_stack() + { + auto* h = head; + while (h != nullptr) + { + auto* hc = h; + h = h->next; + delete hc; + } + } + }; } #endif //BLT_QUEUE_H diff --git a/tests/include/blt_tests.h b/tests/include/blt_tests.h new file mode 100644 index 0000000..5fdc6b6 --- /dev/null +++ b/tests/include/blt_tests.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (C) 2023 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BLT_BLT_TESTS_H +#define BLT_BLT_TESTS_H + +#include +#include +#include +#include + +namespace blt::test +{ + namespace data + { + void run(); + } + + namespace sys + { + + } +} + +#endif //BLT_BLT_TESTS_H diff --git a/tests/src/datastructure_tests.cpp b/tests/src/datastructure_tests.cpp new file mode 100644 index 0000000..3640222 --- /dev/null +++ b/tests/src/datastructure_tests.cpp @@ -0,0 +1,108 @@ +/* + * + * Copyright (C) 2023 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace blt +{ + + constexpr size_t max_size = 100000000; + constexpr size_t min_size = 10000; + + size_t exp(size_t base, size_t e) + { + size_t collect = 1; + for (size_t i = 0; i < e; i++) + collect *= base; + return collect; + } + + void run_size(size_t size) + { + std::vector random_data; + std::random_device dev; + std::mt19937_64 engine(dev()); + std::uniform_int_distribution gen(std::numeric_limits::min(), std::numeric_limits::max()); + + for (size_t i = 0; i < size; i++) + random_data.push_back(gen(engine)); + + auto insertProfile = "Insert (" + std::to_string(size) += ')'; + auto readProfile = "Read (" + std::to_string(size) += ')'; + + std::stack std_stack; + BLT_START_INTERVAL(insertProfile, "std::stack"); + for (size_t i = 0; i < size; i++) + std_stack.push(random_data[i]); + BLT_END_INTERVAL(insertProfile, "std::stack"); + + blt::flat_stack blt_flat_stack; + BLT_START_INTERVAL(insertProfile, "blt::flat_stack"); + for (size_t i = 0; i < size; i++) + blt_flat_stack.push(random_data[i]); + BLT_END_INTERVAL(insertProfile, "blt::flat_stack"); + + blt::linked_stack blt_linked_stack; + BLT_START_INTERVAL(insertProfile, "blt::linked_stack"); + for (size_t i = 0; i < size; i++) + blt_linked_stack.push(random_data[i]); + BLT_END_INTERVAL(insertProfile, "blt::linked_stack"); + + BLT_START_INTERVAL(readProfile, "std::stack"); + for (size_t i = 0; i < size; i++) + { + blt::black_box(std_stack.top()); + std_stack.pop(); + } + BLT_END_INTERVAL(readProfile, "std::stack"); + + BLT_START_INTERVAL(readProfile, "blt::flat_stack"); + for (size_t i = 0; i < size; i++) + { + blt::black_box(blt_flat_stack.top()); + blt_flat_stack.pop(); + } + BLT_END_INTERVAL(readProfile, "blt::flat_stack"); + + BLT_START_INTERVAL(readProfile, "blt::linked_stack"); + for (size_t i = 0; i < size; i++) + { + blt::black_box(blt_linked_stack.top()); + blt_linked_stack.pop(); + } + BLT_END_INTERVAL(readProfile, "blt::linked_stack"); + + BLT_PRINT_PROFILE(insertProfile); + BLT_PRINT_PROFILE(readProfile); + } + + void test::data::run() + { + auto max = static_cast(std::log10(max_size)); + auto min = static_cast(std::log10(min_size)); + for (size_t i = min; i <= max; i++) + run_size(exp(10, i)); + } + +} \ No newline at end of file diff --git a/tests/src/main.cpp b/tests/src/main.cpp index 8d79721..839956a 100755 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -11,10 +11,7 @@ //#include //#include "hashmap_tests.h" //#include -#include -#include -#include -#include +#include std::function test{ [](int i) -> int { @@ -71,6 +68,7 @@ int main(int argc, const char** argv) .setAction(blt::arg_action_t::STORE) .setNArgs('?').build()); parser.addArgument(blt::arg_builder("--utility").setHelp("Run tests on utility functions").setAction(blt::arg_action_t::STORE_TRUE).build()); + parser.addArgument(blt::arg_builder("--data").setHelp("Run tests on data functions").setAction(blt::arg_action_t::STORE_TRUE).build()); auto args = parser.parse_args(argc, argv); @@ -87,6 +85,9 @@ int main(int argc, const char** argv) if (args.contains("--memory")) blt::test::memory::run(); + if (args.contains("--data")) + blt::test::data::run(); + if (args.contains("--nbt")) { auto v = blt::arg_parse::get(args["nbt"]);