v1
Brett 2023-12-16 15:53:02 -05:00
parent bda044de1e
commit 0f48bb8060
4 changed files with 267 additions and 32 deletions

View File

@ -10,14 +10,16 @@
/** /**
* *
*/ */
namespace blt { namespace blt
{
/** /**
* Standard array backed first in first out queue * Standard array backed first in first out queue
* @tparam T type stored in the queue * @tparam T type stored in the queue
*/ */
template<typename T> template<typename T>
class flat_stack { class flat_stack
{
private: private:
int m_size = 16; int m_size = 16;
int m_insertIndex = 0; int m_insertIndex = 0;
@ -28,7 +30,8 @@ namespace blt {
* and deletes the old array from memory. * and deletes the old array from memory.
* @param newSize new size of the internal array * @param newSize new size of the internal array
*/ */
void expand() { void expand()
{
int new_size = m_size * 2; int new_size = m_size * 2;
auto tempData = new T[new_size]; auto tempData = new T[new_size];
for (int i = 0; i < m_insertIndex; i++) for (int i = 0; i < m_insertIndex; i++)
@ -40,8 +43,10 @@ namespace blt {
public: public:
void push(const T& t) { void push(const T& t)
if (m_insertIndex >= m_size) { {
if (m_insertIndex >= m_size)
{
expand(); expand();
} }
m_data[m_insertIndex++] = t; m_data[m_insertIndex++] = t;
@ -51,25 +56,30 @@ namespace blt {
* Warning does not contain runtime error checking! * Warning does not contain runtime error checking!
* @return the element at the "front" of the queue. * @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]; return m_data[m_insertIndex - 1];
} }
void pop() { void pop()
{
if (empty()) if (empty())
return; return;
m_insertIndex--; m_insertIndex--;
} }
[[nodiscard]] inline bool empty() const { [[nodiscard]] inline bool empty() const
{
return m_insertIndex <= 0; return m_insertIndex <= 0;
} }
[[nodiscard]] inline int size() const { [[nodiscard]] inline int size() const
{
return m_insertIndex; return m_insertIndex;
} }
~flat_stack() { ~flat_stack()
{
delete[](m_data); delete[](m_data);
} }
}; };
@ -79,16 +89,19 @@ namespace blt {
* @tparam T type stored in the queue * @tparam T type stored in the queue
*/ */
template<typename T> template<typename T>
class flat_queue { class flat_queue
{
private: private:
int m_size = 16; int m_size = 16;
int m_headIndex = 0; int m_headIndex = 0;
int m_insertIndex = 0; int m_insertIndex = 0;
T* m_data; T* m_data;
/** /**
* Expands the internal array to allow for more storage of elements * Expands the internal array to allow for more storage of elements
*/ */
void expand() { void expand()
{
int new_size = m_size * 2; int new_size = m_size * 2;
int removed_size = m_size - m_headIndex; int removed_size = m_size - m_headIndex;
auto tempData = new T[new_size]; auto tempData = new T[new_size];
@ -103,12 +116,15 @@ namespace blt {
} }
public: public:
flat_queue(): m_data(new T[m_size]) { flat_queue(): m_data(new T[m_size])
{
} }
inline void push(const T& t) { inline void push(const T& t)
if (m_insertIndex+1 >= m_size) { {
if (m_insertIndex + 1 >= m_size)
{
expand(); expand();
} }
m_data[m_insertIndex++] = t; m_data[m_insertIndex++] = t;
@ -118,36 +134,106 @@ namespace blt {
* Warning does not contain runtime error checking! * Warning does not contain runtime error checking!
* @return the element at the "front" of the queue. * @return the element at the "front" of the queue.
*/ */
[[nodiscard]] const T& front() const { [[nodiscard]] const T& front() const
{
return m_data[m_headIndex]; return m_data[m_headIndex];
} }
inline void pop() { [[nodiscard]] T& front()
{
return m_data[m_headIndex];
}
inline void pop()
{
if (empty()) if (empty())
return; return;
m_headIndex++; m_headIndex++;
} }
[[nodiscard]] inline bool empty() const { [[nodiscard]] inline bool empty() const
{
return m_headIndex >= m_size; return m_headIndex >= m_size;
} }
[[nodiscard]] inline int size() const { [[nodiscard]] inline int size() const
{
return m_insertIndex - m_headIndex; return m_insertIndex - m_headIndex;
} }
inline T* begin(){ inline T* begin()
{
return m_data[m_headIndex]; return m_data[m_headIndex];
} }
inline T* end(){ inline T* end()
{
return m_data[m_insertIndex]; return m_data[m_insertIndex];
} }
~flat_queue() { ~flat_queue()
{
delete[](m_data); delete[](m_data);
} }
}; };
template<typename T>
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 #endif //BLT_QUEUE_H

40
tests/include/blt_tests.h Normal file
View File

@ -0,0 +1,40 @@
/*
* <Short Description>
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef BLT_BLT_TESTS_H
#define BLT_BLT_TESTS_H
#include <memory_test.h>
#include <blt/parse/argparse.h>
#include <utility_test.h>
#include <blt/std/utility.h>
namespace blt::test
{
namespace data
{
void run();
}
namespace sys
{
}
}
#endif //BLT_BLT_TESTS_H

View File

@ -0,0 +1,108 @@
/*
* <Short Description>
* 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 <https://www.gnu.org/licenses/>.
*/
#include <blt_tests.h>
#include <blt/std/queue.h>
#include <queue>
#include <stack>
#include <vector>
#include <blt/profiling/profiler_v2.h>
#include <random>
#include <cmath>
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<int> random_data;
std::random_device dev;
std::mt19937_64 engine(dev());
std::uniform_int_distribution gen(std::numeric_limits<int>::min(), std::numeric_limits<int>::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<int> 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<int> 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<int> 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<size_t>(std::log10(max_size));
auto min = static_cast<size_t>(std::log10(min_size));
for (size_t i = min; i <= max; i++)
run_size(exp(10, i));
}
}

View File

@ -11,10 +11,7 @@
//#include <bitset> //#include <bitset>
//#include "hashmap_tests.h" //#include "hashmap_tests.h"
//#include <functional> //#include <functional>
#include <memory_test.h> #include <blt_tests.h>
#include <blt/parse/argparse.h>
#include <utility_test.h>
#include <blt/std/utility.h>
std::function<int(int i)> test{ std::function<int(int i)> test{
[](int i) -> int { [](int i) -> int {
@ -71,6 +68,7 @@ int main(int argc, const char** argv)
.setAction(blt::arg_action_t::STORE) .setAction(blt::arg_action_t::STORE)
.setNArgs('?').build()); .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("--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); auto args = parser.parse_args(argc, argv);
@ -87,6 +85,9 @@ int main(int argc, const char** argv)
if (args.contains("--memory")) if (args.contains("--memory"))
blt::test::memory::run(); blt::test::memory::run();
if (args.contains("--data"))
blt::test::data::run();
if (args.contains("--nbt")) if (args.contains("--nbt"))
{ {
auto v = blt::arg_parse::get<std::string>(args["nbt"]); auto v = blt::arg_parse::get<std::string>(args["nbt"]);