Format source files

This commit is contained in:
2023-02-18 10:37:38 +01:00
parent 76d93bb1cf
commit d09d4d3d92
12 changed files with 793 additions and 850 deletions

View File

@@ -4,7 +4,7 @@ CFLAGS = -std=c++17 -Wall -g -Wextra
CPPS = $(wildcard test/*.cpp) CPPS = $(wildcard test/*.cpp)
EXES = $(patsubst %.cpp, %.out, $(CPPS)) EXES = $(patsubst %.cpp, %.out, $(CPPS))
.PHONY: all clean rebuild check .PHONY: all clean rebuild check format
all: $(EXES) all: $(EXES)
@@ -19,5 +19,11 @@ EXESQUOTED = $(patsubst %, "%", $(EXES))
check: all check: all
./execute-all.sh ./execute-all.sh
format:
find src/ -name *.cpp -exec clang-format -i {} \;
find src/ -name *.hpp -exec clang-format -i {} \;
find test/ -name *.cpp -exec clang-format -i {} \;
find test/ -name *.hpp -exec clang-format -i {} \;
%.out: %.cpp %.out: %.cpp
$(CC) $(CFLAGS) $< -o $@ $(CC) $(CFLAGS) $< -o $@

View File

@@ -5,187 +5,174 @@
namespace List namespace List
{ {
template<class T> template<class T> struct Node
struct Node {
{ T value;
T value; std::unique_ptr<Node<T>> next;
std::unique_ptr<Node<T>> next;
Node(T const & _value) Node(T const & _value) : value(_value), next(nullptr) { }
: value(_value), };
next(nullptr)
{}
};
template<class T> template<class T> class List {
class List private:
{ std::unique_ptr<Node<T>> root;
private: Node<T> * tailPtr;
std::unique_ptr<Node<T>> root; std::size_t size;
Node<T> * tailPtr;
std::size_t size;
public: public:
void Append(T const & value) void Append(T const & value)
{ {
if(size == 0) if(size == 0)
{ {
root = std::make_unique<Node<T>>(value); root = std::make_unique<Node<T>>(value);
tailPtr = root.get(); tailPtr = root.get();
++size; ++size;
return; return;
} }
tailPtr->next = std::make_unique<Node<T>>(value); tailPtr->next = std::make_unique<Node<T>>(value);
tailPtr = tailPtr->next.get(); tailPtr = tailPtr->next.get();
++size; ++size;
} }
void Prepend(T const & value) void Prepend(T const & value)
{ {
if(size == 0) if(size == 0)
{ {
root = std::make_unique<Node<T>>(value); root = std::make_unique<Node<T>>(value);
tailPtr = root.get(); tailPtr = root.get();
++size; ++size;
return; return;
} }
auto newRoot = std::make_unique<Node<T>>(value); auto newRoot = std::make_unique<Node<T>>(value);
newRoot->next.swap(root); newRoot->next.swap(root);
root.swap(newRoot); root.swap(newRoot);
++size; ++size;
} }
void Insert(T const & value, std::size_t const index) void Insert(T const & value, std::size_t const index)
{ {
if(index >= size) if(index >= size)
{ {
throw std::out_of_range("Index is greater or equal to size."); throw std::out_of_range("Index is greater or equal to size.");
} }
if(index == 0u) if(index == 0u)
{ {
Prepend(value); Prepend(value);
return; return;
} }
++size; ++size;
Node<T> * prevPtr = root.get(); Node<T> * prevPtr = root.get();
Node<T> * curPtr = root->next.get(); Node<T> * curPtr = root->next.get();
std::size_t currentIndex = 1u; std::size_t currentIndex = 1u;
while(currentIndex < index) while(currentIndex < index)
{ {
prevPtr = curPtr; prevPtr = curPtr;
curPtr = curPtr->next.get(); curPtr = curPtr->next.get();
++currentIndex; ++currentIndex;
} }
auto newNode = std::make_unique<Node<T>>(value); auto newNode = std::make_unique<Node<T>>(value);
newNode->next.swap(prevPtr->next); newNode->next.swap(prevPtr->next);
prevPtr->next.swap(newNode); prevPtr->next.swap(newNode);
} }
void Delete(std::size_t const index) void Delete(std::size_t const index)
{ {
if(index >= size) if(index >= size)
{ {
throw std::out_of_range("Index is greater or equal to size."); throw std::out_of_range("Index is greater or equal to size.");
} }
--size; --size;
if(index == 0u) if(index == 0u)
{ {
if(size == 0u) if(size == 0u)
{ {
root.release(); root.release();
tailPtr = nullptr; tailPtr = nullptr;
} }
else else
{ {
root = std::move(root->next); root = std::move(root->next);
} }
return; return;
} }
// Is index last element? Note that we subtracted 1 from size above // Is index last element? Note that we subtracted 1 from size above
if(index == size) if(index == size)
{ {
Node<T> * curPtr = root.get(); Node<T> * curPtr = root.get();
while(curPtr->next.get() != tailPtr) while(curPtr->next.get() != tailPtr)
{ {
curPtr = curPtr->next.get(); curPtr = curPtr->next.get();
} }
tailPtr = curPtr; tailPtr = curPtr;
tailPtr->next.release(); tailPtr->next.release();
return; return;
} }
Node<T> * prevPtr = root.get(); Node<T> * prevPtr = root.get();
Node<T> * curPtr = prevPtr->next.get(); Node<T> * curPtr = prevPtr->next.get();
std::size_t currentIndex = 1u; std::size_t currentIndex = 1u;
while(currentIndex < index) while(currentIndex < index)
{ {
++currentIndex; ++currentIndex;
prevPtr = curPtr; prevPtr = curPtr;
curPtr = curPtr->next.get(); curPtr = curPtr->next.get();
} }
prevPtr->next = std::move(curPtr->next); prevPtr->next = std::move(curPtr->next);
} }
T & Front() T & Front()
{ {
if(size == 0u) if(size == 0u)
{ {
throw std::out_of_range("List is empty."); throw std::out_of_range("List is empty.");
} }
return root->value; return root->value;
} }
T & Back() T & Back()
{ {
if(size == 0u) if(size == 0u)
{ {
throw std::out_of_range("List is empty."); throw std::out_of_range("List is empty.");
} }
return tailPtr->value; return tailPtr->value;
} }
T & operator[](std::size_t const index) T & operator[](std::size_t const index)
{ {
if(index >= size) if(index >= size)
{ {
throw std::out_of_range("Index is greater or equal to size."); throw std::out_of_range("Index is greater or equal to size.");
} }
Node<T> * currentNode = root.get(); Node<T> * currentNode = root.get();
std::size_t currentIndex = 0u; std::size_t currentIndex = 0u;
while(currentIndex < index) while(currentIndex < index)
{ {
currentNode = currentNode->next.get(); currentNode = currentNode->next.get();
++currentIndex; ++currentIndex;
} }
return currentNode->value; return currentNode->value;
} }
std::size_t GetSize() const std::size_t GetSize() const { return size; }
{
return size;
}
List() List() : root(nullptr), tailPtr(nullptr), size(0) { }
: root(nullptr), };
tailPtr(nullptr),
size(0)
{}
};
} }

View File

@@ -1,76 +1,65 @@
#pragma once #pragma once
#include "vector.hpp" #include "vector.hpp"
template<class T> template<class T> class RingBuffer {
class RingBuffer
{
private: private:
Vector<T> data; Vector<T> data;
std::size_t head, tail; std::size_t head, tail;
void AdvanceHead() void AdvanceHead()
{ {
++head; ++head;
if(head >= data.GetSize()) if(head >= data.GetSize())
{ {
head = 0; head = 0;
} }
} }
void AdvanceTail() void AdvanceTail()
{ {
++tail; ++tail;
if(tail >= data.GetSize()) if(tail >= data.GetSize())
{ {
tail = 0; tail = 0;
} }
if(tail == head) if(tail == head)
{ {
AdvanceHead(); AdvanceHead();
} }
} }
public: public:
void Push(T const & value) void Push(T const & value)
{ {
data[tail] = value; data[tail] = value;
AdvanceTail(); AdvanceTail();
} }
T Pop() T Pop()
{ {
if(head == tail) if(head == tail)
{ {
throw std::out_of_range("Cannot retrieve value when size is 0"); throw std::out_of_range("Cannot retrieve value when size is 0");
} }
T const & toReturn = data[head]; T const & toReturn = data[head];
AdvanceHead(); AdvanceHead();
return toReturn; return toReturn;
} }
std::size_t GetSize() const std::size_t GetSize() const
{ {
if(head <= tail) if(head <= tail)
{ {
return tail - head; return tail - head;
} }
else else
{ {
return tail + (data.GetSize() - head); return tail + (data.GetSize() - head);
} }
} }
bool IsEmpty() const bool IsEmpty() const { return head == tail; }
{
return head == tail;
}
RingBuffer(std::size_t const size) RingBuffer(std::size_t const size) : data(), head(0), tail(0) { data.Resize(size + 1ul); }
: data(),
head(0),
tail(0)
{
data.Resize(size + 1ul);
}
}; };

View File

@@ -1,46 +1,38 @@
#pragma once #pragma once
#include "vector.hpp" #include "vector.hpp"
template<class T> template<class T> class Stack {
class Stack
{
private: private:
Vector<T> data; Vector<T> data;
std::size_t actualSize; std::size_t actualSize;
public: public:
void Push(T const & value) void Push(T const & value)
{ {
++actualSize; ++actualSize;
if(actualSize > data.GetSize()) if(actualSize > data.GetSize())
{ {
data.Resize(actualSize); data.Resize(actualSize);
} }
data[actualSize - 1ul] = value; data[actualSize - 1ul] = value;
} }
T Pop() T Pop()
{ {
if(actualSize == 0ul) if(actualSize == 0ul)
{ {
throw std::out_of_range("Cannot pop an empty stack."); throw std::out_of_range("Cannot pop an empty stack.");
} }
auto const retval = data[actualSize - 1ul]; auto const retval = data[actualSize - 1ul];
--actualSize; --actualSize;
data.Resize(actualSize); data.Resize(actualSize);
return retval; return retval;
} }
std::size_t GetSize() const std::size_t GetSize() const { return actualSize; }
{
return actualSize;
}
Stack() Stack() : actualSize(0) { }
: actualSize(0)
{
}
}; };

View File

@@ -2,85 +2,73 @@
#include <cstdlib> #include <cstdlib>
#include <stdexcept> #include <stdexcept>
template<class T> template<class T> class Vector {
class Vector
{
private: private:
T * data; T * data;
std::size_t reserveSize; std::size_t reserveSize;
std::size_t size; std::size_t size;
void Allocate(std::size_t const allocationSize) void Allocate(std::size_t const allocationSize)
{ {
if(allocationSize == 0ul) if(allocationSize == 0ul)
{ {
std::free(data); std::free(data);
data = nullptr; data = nullptr;
reserveSize = 0ul; reserveSize = 0ul;
return; return;
} }
if(allocationSize == size) if(allocationSize == size)
{ {
return; return;
} }
void * result = std::realloc(data, sizeof(T) * allocationSize); void * result = std::realloc(data, sizeof(T) * allocationSize);
if(result == nullptr) if(result == nullptr)
{ {
throw std::runtime_error("Cannot allocate the requested size of memory."); throw std::runtime_error("Cannot allocate the requested size of memory.");
} }
reserveSize = allocationSize; reserveSize = allocationSize;
data = reinterpret_cast<T *>(result); data = reinterpret_cast<T *>(result);
} }
public: public:
void Resize(std::size_t const newSize) void Resize(std::size_t const newSize)
{ {
if (newSize > reserveSize) if(newSize > reserveSize)
{ {
Allocate(newSize); Allocate(newSize);
size = newSize; size = newSize;
return; return;
} }
size = newSize; size = newSize;
} }
void Reserve(std::size_t const newReserveSize) void Reserve(std::size_t const newReserveSize)
{ {
if(newReserveSize < size) if(newReserveSize < size)
{ {
Allocate(size); Allocate(size);
return; return;
} }
Allocate(newReserveSize); Allocate(newReserveSize);
} }
T & operator[](std::size_t const index) T & operator[](std::size_t const index)
{ {
if(index >= size) if(index >= size)
{ {
throw std::out_of_range("Index is greater or equal to size."); throw std::out_of_range("Index is greater or equal to size.");
} }
return data[index]; return data[index];
} }
std::size_t GetSize() const std::size_t GetSize() const { return size; }
{
return size;
}
std::size_t GetReserveSize() const std::size_t GetReserveSize() const { return reserveSize; }
{
return reserveSize;
}
Vector() Vector() : data(nullptr), reserveSize(0ul), size(0ul) { }
: data(nullptr),
reserveSize(0ul),
size(0ul)
{}
}; };

View File

@@ -3,145 +3,126 @@
namespace BinaryTree namespace BinaryTree
{ {
template <class T> template<class T> struct Node
struct Node {
{ T value;
T value;
std::unique_ptr<Node<T>> left; std::unique_ptr<Node<T>> left;
std::unique_ptr<Node<T>> right; std::unique_ptr<Node<T>> right;
bool HasChildren() const bool HasChildren() const { return static_cast<bool>(left) || static_cast<bool>(right); }
{
return static_cast<bool>(left) || static_cast<bool>(right);
}
bool IsLeaf() const bool IsLeaf() const { return !HasChildren(); }
{
return !HasChildren();
}
Node(T const &_value) Node(T const & _value) : value(_value), left(nullptr), right(nullptr) { }
: value(_value), };
left(nullptr),
right(nullptr)
{
}
};
template <class T> template<class T> class Tree {
class Tree private:
{ std::unique_ptr<Node<T>> root;
private:
std::unique_ptr<Node<T>> root;
T ExtractSmallestLeaf(std::unique_ptr<Node<T>> &node) T ExtractSmallestLeaf(std::unique_ptr<Node<T>> & node)
{ {
std::unique_ptr<Node<T>> *nodePtr = &(node); std::unique_ptr<Node<T>> * nodePtr = &(node);
while ((*nodePtr)->HasChildren()) while((*nodePtr)->HasChildren())
{ {
if((*nodePtr)->left) if((*nodePtr)->left)
{ {
nodePtr = &((*nodePtr)->left); nodePtr = &((*nodePtr)->left);
} }
else else
{ {
T value = (*nodePtr)->value; T value = (*nodePtr)->value;
(*nodePtr) = std::move((*nodePtr)->right); (*nodePtr) = std::move((*nodePtr)->right);
return value; return value;
} }
} }
T value = (*nodePtr)->value; T value = (*nodePtr)->value;
(*nodePtr).release(); (*nodePtr).release();
return value; return value;
} }
void DeleteNode(std::unique_ptr<Node<T>> & node) void DeleteNode(std::unique_ptr<Node<T>> & node)
{ {
if(!node || node->IsLeaf()) if(!node || node->IsLeaf())
{ {
node.release(); node.release();
return; return;
} }
if(!(node->left)) if(!(node->left))
{ {
node = std::move(node->right); node = std::move(node->right);
return; return;
} }
if(!(node->right)) if(!(node->right))
{ {
node = std::move(node->left); node = std::move(node->left);
return; return;
} }
// In order successor // In order successor
auto newNodeValue = ExtractSmallestLeaf(node->right); auto newNodeValue = ExtractSmallestLeaf(node->right);
node->value = newNodeValue; node->value = newNodeValue;
} }
std::unique_ptr<Node<T>> & FindNode(T const & value) std::unique_ptr<Node<T>> & FindNode(T const & value)
{ {
std::unique_ptr<Node<T>> *currentPtr = &root; std::unique_ptr<Node<T>> * currentPtr = &root;
while (*currentPtr && (*currentPtr)->value != value) while(*currentPtr && (*currentPtr)->value != value)
{ {
if ((*currentPtr)->value > value) if((*currentPtr)->value > value)
{ {
currentPtr = &((*currentPtr)->left); currentPtr = &((*currentPtr)->left);
} }
else else
{ {
currentPtr = &((*currentPtr)->right); currentPtr = &((*currentPtr)->right);
} }
} }
return *currentPtr; return *currentPtr;
} }
public: public:
void Insert(T const & value) void Insert(T const & value)
{ {
std::unique_ptr<Node<T>> *currentPtr = &root; std::unique_ptr<Node<T>> * currentPtr = &root;
while (*currentPtr) while(*currentPtr)
{ {
if ((*currentPtr)->value > value) if((*currentPtr)->value > value)
{ {
currentPtr = &((*currentPtr)->left); currentPtr = &((*currentPtr)->left);
} }
else else
{ {
currentPtr = &((*currentPtr)->right); currentPtr = &((*currentPtr)->right);
} }
} }
*currentPtr = std::make_unique<Node<T>>(value); *currentPtr = std::make_unique<Node<T>>(value);
} }
void InsertNoDuplicates(T const & value) void InsertNoDuplicates(T const & value)
{ {
auto & toInsertIn = FindNode(value); auto & toInsertIn = FindNode(value);
if(toInsertIn) if(toInsertIn)
{ {
return; return;
} }
toInsertIn = std::make_unique<Node<T>>(value); toInsertIn = std::make_unique<Node<T>>(value);
} }
bool Contains(T const & value) bool Contains(T const & value) { return static_cast<bool>(FindNode(value)); }
{
return static_cast<bool>(FindNode(value));
}
void Delete(T const & value) void Delete(T const & value)
{ {
auto & node = FindNode(value); auto & node = FindNode(value);
DeleteNode(node); DeleteNode(node);
} }
Tree() Tree() : root(nullptr) { }
: root(nullptr) };
{}
};
} // namespace BinaryTree } // namespace BinaryTree

View File

@@ -1,182 +1,183 @@
#include "../src/tree/binarytree.hpp" #include "../src/tree/binarytree.hpp"
#include "testutil.hpp" #include "testutil.hpp"
#include <vector>
#include <unordered_set> #include <unordered_set>
#include <vector>
void FillWithUniqueRandomNumbers(BinaryTree::Tree<unsigned> & tree, void FillWithUniqueRandomNumbers(
std::unordered_set<unsigned> & control, BinaryTree::Tree<unsigned> & tree,
unsigned const count = 10000u) std::unordered_set<unsigned> & control,
unsigned const count = 10000u)
{ {
for(unsigned i = 0u; i < count; ++i) for(unsigned i = 0u; i < count; ++i)
{ {
unsigned const value = Util::GetRandomNumber(); unsigned const value = Util::GetRandomNumber();
control.insert(value); control.insert(value);
tree.InsertNoDuplicates(value); tree.InsertNoDuplicates(value);
} }
} }
bool TestInsert() bool TestInsert()
{ {
unsigned const testSize = 4096; unsigned const testSize = 4096;
std::vector<unsigned> control; std::vector<unsigned> control;
BinaryTree::Tree<unsigned> tree; BinaryTree::Tree<unsigned> tree;
for(unsigned i = 0u; i < testSize; ++i) for(unsigned i = 0u; i < testSize; ++i)
{ {
unsigned const value = Util::GetRandomNumber(); unsigned const value = Util::GetRandomNumber();
control.push_back(value); control.push_back(value);
tree.Insert(value); tree.Insert(value);
} }
for(auto const & num : control) for(auto const & num: control)
{ {
if(!tree.Contains(num)) if(!tree.Contains(num))
{ {
//std::printf("\tValue %u inserted but cannot be found!\n", num); //std::printf("\tValue %u inserted but cannot be found!\n", num);
return false; return false;
} }
} }
return true; return true;
} }
bool TestInsertNoDuplicates() bool TestInsertNoDuplicates()
{ {
std::unordered_set<unsigned> control; std::unordered_set<unsigned> control;
BinaryTree::Tree<unsigned> tree; BinaryTree::Tree<unsigned> tree;
FillWithUniqueRandomNumbers(tree, control); FillWithUniqueRandomNumbers(tree, control);
for(auto const & num : control) for(auto const & num: control)
{ {
if(!tree.Contains(num)) if(!tree.Contains(num))
{ {
//std::printf("\tValue %u inserted but cannot be found!\n", num); //std::printf("\tValue %u inserted but cannot be found!\n", num);
return false; return false;
} }
} }
return true; return true;
} }
bool TestDeletion() bool TestDeletion()
{ {
std::unordered_set<unsigned> control; std::unordered_set<unsigned> control;
BinaryTree::Tree<unsigned> tree; BinaryTree::Tree<unsigned> tree;
FillWithUniqueRandomNumbers(tree, control); FillWithUniqueRandomNumbers(tree, control);
std::vector<unsigned> deletedValues; std::vector<unsigned> deletedValues;
unsigned const toDeleteCount = control.size() / 4; unsigned const toDeleteCount = control.size() / 4;
for(unsigned i = 0u; i < toDeleteCount; ++i) for(unsigned i = 0u; i < toDeleteCount; ++i)
{ {
auto const valueTodelete = Util::GetRandomNumber(); auto const valueTodelete = Util::GetRandomNumber();
auto controlElement = control.find(valueTodelete); auto controlElement = control.find(valueTodelete);
if(controlElement != control.end()) if(controlElement != control.end())
{ {
control.erase(controlElement); control.erase(controlElement);
tree.Delete(valueTodelete); tree.Delete(valueTodelete);
deletedValues.push_back(valueTodelete); deletedValues.push_back(valueTodelete);
} }
} }
for(auto const & num : control) for(auto const & num: control)
{ {
if(!tree.Contains(num)) if(!tree.Contains(num))
{ {
std::puts("[ERROR] Tree does not contain a value that it should."); std::puts("[ERROR] Tree does not contain a value that it should.");
//std::printf("Value %u inserted but cannot be found!\n", num); //std::printf("Value %u inserted but cannot be found!\n", num);
return false; return false;
} }
} }
for(auto const & num : deletedValues) for(auto const & num: deletedValues)
{ {
if(tree.Contains(num)) if(tree.Contains(num))
{ {
std::puts("[ERROR] Tree contains deleted value that it should not."); std::puts("[ERROR] Tree contains deleted value that it should not.");
return false; return false;
} }
} }
return true; return true;
} }
bool TestDeletionCase( bool TestDeletionCase(
std::vector<unsigned> const toInsert, std::vector<unsigned> const toInsert,
std::vector<unsigned> const toDelete, std::vector<unsigned> const toDelete,
std::vector<unsigned> const result) std::vector<unsigned> const result)
{ {
BinaryTree::Tree<unsigned> tree; BinaryTree::Tree<unsigned> tree;
for(auto n : toInsert) for(auto n: toInsert)
{ {
tree.Insert(n); tree.Insert(n);
} }
for(auto n : toDelete) for(auto n: toDelete)
{ {
tree.Delete(n); tree.Delete(n);
} }
bool ok = true; bool ok = true;
for(auto n : result) for(auto n: result)
{ {
if(!tree.Contains(n)) if(!tree.Contains(n))
{ {
std::printf("[ERROR] Tree does not contain value %u.\n", n); std::printf("[ERROR] Tree does not contain value %u.\n", n);
ok = false; ok = false;
} }
} }
for(auto n : toDelete) for(auto n: toDelete)
{ {
if(tree.Contains(n)) if(tree.Contains(n))
{ {
std::printf("[ERROR] Tree contains deleted value %u.\n", n); std::printf("[ERROR] Tree contains deleted value %u.\n", n);
ok = false; ok = false;
} }
} }
return ok; return ok;
} }
bool TestDeletionCases() bool TestDeletionCases()
{ {
std::puts("[INFO] Testing deleting root with single child right."); std::puts("[INFO] Testing deleting root with single child right.");
TestDeletionCase( TestDeletionCase(
std::vector<unsigned> { 10, 12, 11, 13}, std::vector<unsigned> {10, 12, 11, 13},
std::vector<unsigned> { 10 }, std::vector<unsigned> {10},
std::vector<unsigned> { 12, 11, 13 }); std::vector<unsigned> {12, 11, 13});
std::puts("[INFO] Testing deleting root with single child left."); std::puts("[INFO] Testing deleting root with single child left.");
TestDeletionCase( TestDeletionCase(
std::vector<unsigned> { 15, 12, 11, 13}, std::vector<unsigned> {15, 12, 11, 13},
std::vector<unsigned> { 15 }, std::vector<unsigned> {15},
std::vector<unsigned> { 12, 11, 13 }); std::vector<unsigned> {12, 11, 13});
std::puts("[INFO] Testing deleting root with 2 children but no child right left."); std::puts("[INFO] Testing deleting root with 2 children but no child right left.");
TestDeletionCase( TestDeletionCase(
std::vector<unsigned> { 15, 10, 20, 22, 25, 18, 5}, std::vector<unsigned> {15, 10, 20, 22, 25, 18, 5},
std::vector<unsigned> { 20 }, std::vector<unsigned> {20},
std::vector<unsigned> { 15, 10, 22, 25, 18, 5 }); std::vector<unsigned> {15, 10, 22, 25, 18, 5});
std::puts("[INFO] Testing deleting root with 2 children."); std::puts("[INFO] Testing deleting root with 2 children.");
TestDeletionCase( TestDeletionCase(
std::vector<unsigned> { 50, 40, 60, 75, 55, 45, 42, 58 }, std::vector<unsigned> {50, 40, 60, 75, 55, 45, 42, 58},
std::vector<unsigned> { 50 }, std::vector<unsigned> {50},
std::vector<unsigned> { 40, 60, 75, 55, 45, 42, 58 }); std::vector<unsigned> {40, 60, 75, 55, 45, 42, 58});
return true; return true;
} }
int main() int main()
{ {
Test::Execute(TestInsert, "Insertion and find test"); Test::Execute(TestInsert, "Insertion and find test");
Test::Execute(TestInsertNoDuplicates, "Insertion without duplicates test"); Test::Execute(TestInsertNoDuplicates, "Insertion without duplicates test");
Test::Execute(TestDeletion, "Insertion and deletion test"); Test::Execute(TestDeletion, "Insertion and deletion test");
Test::Execute(TestDeletionCases, "Deletion cases test"); Test::Execute(TestDeletionCases, "Deletion cases test");
return 0; return 0;
} }

View File

@@ -3,135 +3,135 @@
bool TestAppending() bool TestAppending()
{ {
unsigned const testSize = 5; unsigned const testSize = 5;
std::vector<unsigned> truth; std::vector<unsigned> truth;
List::List<unsigned> list; List::List<unsigned> list;
truth.resize(testSize); truth.resize(testSize);
for(unsigned i = 0; i < testSize; ++i) for(unsigned i = 0; i < testSize; ++i)
{ {
unsigned const value = Util::GetRandomNumber(); unsigned const value = Util::GetRandomNumber();
truth[i] = value; truth[i] = value;
list.Append(value); list.Append(value);
} }
for(unsigned i = 0; i < testSize; ++i) for(unsigned i = 0; i < testSize; ++i)
{ {
if(truth[i] != list[i]) if(truth[i] != list[i])
{ {
return false; return false;
} }
} }
return true; return true;
} }
bool TestPrepending() bool TestPrepending()
{ {
unsigned const testSize = 5; unsigned const testSize = 5;
std::vector<unsigned> truth; std::vector<unsigned> truth;
List::List<unsigned> list; List::List<unsigned> list;
truth.resize(testSize); truth.resize(testSize);
for(unsigned i = testSize; i > 0; --i) for(unsigned i = testSize; i > 0; --i)
{ {
unsigned const value = Util::GetRandomNumber(); unsigned const value = Util::GetRandomNumber();
truth[i - 1] = value; truth[i - 1] = value;
list.Prepend(value); list.Prepend(value);
} }
for(unsigned i = 0; i < testSize; ++i) for(unsigned i = 0; i < testSize; ++i)
{ {
if(truth[i] != list[i]) if(truth[i] != list[i])
{ {
return false; return false;
} }
} }
return true; return true;
} }
bool TestPrependAppendMix() bool TestPrependAppendMix()
{ {
std::vector<unsigned> numbers = { 5, 6, 4, 7, 3, 8, 2, 9, 1, 10 }; std::vector<unsigned> numbers = {5, 6, 4, 7, 3, 8, 2, 9, 1, 10};
List::List<unsigned> list; List::List<unsigned> list;
for(unsigned i = 0; i < numbers.size(); i += 2) for(unsigned i = 0; i < numbers.size(); i += 2)
{ {
list.Prepend(numbers[i]); list.Prepend(numbers[i]);
list.Append(numbers[i + 1]); list.Append(numbers[i + 1]);
} }
for(unsigned i = 0; i < list.GetSize(); ++i) for(unsigned i = 0; i < list.GetSize(); ++i)
{ {
if(list[i] != i + 1) if(list[i] != i + 1)
{ {
return false; return false;
} }
} }
return true; return true;
} }
bool TestDeletion() bool TestDeletion()
{ {
List::List<unsigned> list; List::List<unsigned> list;
for(unsigned i = 1; i < 8; ++i) for(unsigned i = 1; i < 8; ++i)
{ {
list.Append(i); list.Append(i);
} }
for(unsigned i = 0; i < list.GetSize(); ++i) for(unsigned i = 0; i < list.GetSize(); ++i)
{ {
list.Delete(i); list.Delete(i);
} }
for(unsigned i = 0; i < list.GetSize(); ++i) for(unsigned i = 0; i < list.GetSize(); ++i)
{ {
if(list[i] % 2 != 0) if(list[i] % 2 != 0)
{ {
return false; return false;
} }
} }
return true; return true;
} }
bool TestInsertion() bool TestInsertion()
{ {
unsigned const testSize = 11; unsigned const testSize = 11;
List::List<unsigned> list; List::List<unsigned> list;
for(unsigned i = 1; i < testSize; i += 2) for(unsigned i = 1; i < testSize; i += 2)
{ {
list.Append(i); list.Append(i);
} }
for(unsigned i = 1; i < testSize - 2; i += 2) for(unsigned i = 1; i < testSize - 2; i += 2)
{ {
list.Insert(i + 1, i); list.Insert(i + 1, i);
} }
for(unsigned i = 1; i <= list.GetSize(); ++i) for(unsigned i = 1; i <= list.GetSize(); ++i)
{ {
if(list[i - 1] != i) if(list[i - 1] != i)
{ {
return false; return false;
} }
} }
return true; return true;
} }
int main() int main()
{ {
Test::Execute(TestAppending, "Appending test"); Test::Execute(TestAppending, "Appending test");
Test::Execute(TestPrepending, "Prepending test"); Test::Execute(TestPrepending, "Prepending test");
Test::Execute(TestPrependAppendMix, "Prepend append mix test"); Test::Execute(TestPrependAppendMix, "Prepend append mix test");
Test::Execute(TestDeletion, "Deletion test"); Test::Execute(TestDeletion, "Deletion test");
Test::Execute(TestInsertion, "Insertion test"); Test::Execute(TestInsertion, "Insertion test");
return 0; return 0;
} }

View File

@@ -3,58 +3,58 @@
bool TestInsertion() bool TestInsertion()
{ {
std::size_t const testSize = 512u; std::size_t const testSize = 512u;
std::vector<unsigned> truth; std::vector<unsigned> truth;
truth.resize(testSize); truth.resize(testSize);
RingBuffer<unsigned> ringBuffer(512u); RingBuffer<unsigned> ringBuffer(512u);
for(std::size_t i = 0; i < testSize; ++i) for(std::size_t i = 0; i < testSize; ++i)
{ {
truth[i] = Util::GetRandomNumber(); truth[i] = Util::GetRandomNumber();
ringBuffer.Push(truth[i]); ringBuffer.Push(truth[i]);
} }
for(std::size_t i = 0; i < testSize; ++i) for(std::size_t i = 0; i < testSize; ++i)
{ {
if(truth[i] != ringBuffer.Pop()) if(truth[i] != ringBuffer.Pop())
{ {
return false; return false;
} }
} }
return true; return true;
} }
bool TestWrapAround() bool TestWrapAround()
{ {
std::size_t const testSize = 32u; std::size_t const testSize = 32u;
RingBuffer<unsigned> ringBuffer(testSize); RingBuffer<unsigned> ringBuffer(testSize);
for(std::size_t i = 0; i < testSize / 2u; ++i) for(std::size_t i = 0; i < testSize / 2u; ++i)
{ {
ringBuffer.Push(42u); ringBuffer.Push(42u);
} }
for(std::size_t i = 0; i < testSize; ++i) for(std::size_t i = 0; i < testSize; ++i)
{ {
ringBuffer.Push(i); ringBuffer.Push(i);
} }
for(std::size_t i = 0; i < testSize; ++i) for(std::size_t i = 0; i < testSize; ++i)
{ {
if(ringBuffer.Pop() != i) if(ringBuffer.Pop() != i)
{ {
return false; return false;
} }
} }
return true; return true;
} }
int main() int main()
{ {
Test::Execute(TestInsertion, "Insertion test"); Test::Execute(TestInsertion, "Insertion test");
Test::Execute(TestWrapAround, "Wrap around test"); Test::Execute(TestWrapAround, "Wrap around test");
return 0; return 0;
} }

View File

@@ -4,32 +4,32 @@
bool TestStack() bool TestStack()
{ {
std::size_t testSize = 512ul; std::size_t testSize = 512ul;
std::stack<unsigned> truth; std::stack<unsigned> truth;
Stack<unsigned> stack; Stack<unsigned> stack;
for(std::size_t i = 0; i < testSize; ++i) for(std::size_t i = 0; i < testSize; ++i)
{ {
unsigned const toInsert = Util::GetRandomNumber(); unsigned const toInsert = Util::GetRandomNumber();
truth.push(toInsert); truth.push(toInsert);
stack.Push(toInsert); stack.Push(toInsert);
} }
while(!truth.empty()) while(!truth.empty())
{ {
if(truth.top() != stack.Pop()) if(truth.top() != stack.Pop())
{ {
return false; return false;
} }
truth.pop(); truth.pop();
} }
return true; return true;
} }
int main() int main()
{ {
Test::Execute(TestStack, "Pop push test"); Test::Execute(TestStack, "Pop push test");
return 0; return 0;
} }

View File

@@ -7,57 +7,57 @@
namespace Util namespace Util
{ {
unsigned static GetRandomNumber() unsigned static GetRandomNumber()
{ {
static std::default_random_engine eng; static std::default_random_engine eng;
static std::uniform_int_distribution<unsigned> valueDist(0u, 8096u); static std::uniform_int_distribution<unsigned> valueDist(0u, 8096u);
return valueDist(eng); return valueDist(eng);
} }
}; };
namespace Test namespace Test
{ {
void Execute(bool (*testFunction)(void), char const * const message) void Execute(bool (*testFunction)(void), char const * const message)
{ {
try try
{ {
if(testFunction()) if(testFunction())
{ {
std::printf("[PASS] %s\n", message); std::printf("[PASS] %s\n", message);
} }
else else
{ {
std::printf("[FAIL] %s\n", message); std::printf("[FAIL] %s\n", message);
} }
} }
catch(std::exception & e) catch(std::exception & e)
{ {
std::printf("[FAIL] Exception thrown during execution of <%s>, error: %s\n", message, e.what()); std::printf("[FAIL] Exception thrown during execution of <%s>, error: %s\n", message, e.what());
} }
} }
void Execute(bool (*testFunction)(std::vector<std::string> &), char const * const message) void Execute(bool (*testFunction)(std::vector<std::string> &), char const * const message)
{ {
std::vector<std::string> issues; std::vector<std::string> issues;
try try
{ {
if(testFunction(issues)) if(testFunction(issues))
{ {
std::printf("[PASS] %s\n", message); std::printf("[PASS] %s\n", message);
} }
else else
{ {
std::printf("[FAIL] %s\n", message); std::printf("[FAIL] %s\n", message);
for(auto & issue : issues) for(auto & issue: issues)
{ {
std::printf(" Issue: %s\n", issue.c_str()); std::printf(" Issue: %s\n", issue.c_str());
} }
} }
} }
catch(std::exception & e) catch(std::exception & e)
{ {
std::printf("[FAIL] Exception thrown during execution of <%s>, error: %s\n", message, e.what()); std::printf("[FAIL] Exception thrown during execution of <%s>, error: %s\n", message, e.what());
} }
} }
}; };

View File

@@ -1,111 +1,110 @@
#include "../src/sequential/vector.hpp" #include "../src/sequential/vector.hpp"
#include "testutil.hpp" #include "testutil.hpp"
void FillWithSequentialNumbers(Vector<unsigned> & vector, void FillWithSequentialNumbers(Vector<unsigned> & vector, unsigned const count = 1024u)
unsigned const count = 1024u)
{ {
for(unsigned i = 0; i < count; ++i) for(unsigned i = 0; i < count; ++i)
{ {
vector[i] = i; vector[i] = i;
} }
} }
bool TestInsertion() bool TestInsertion()
{ {
unsigned const targetSize = 1024u; unsigned const targetSize = 1024u;
Vector<unsigned> vector; Vector<unsigned> vector;
try try
{ {
vector.Resize(targetSize); vector.Resize(targetSize);
} }
catch(std::exception & e) catch(std::exception & e)
{ {
return false; return false;
} }
FillWithSequentialNumbers(vector, targetSize); FillWithSequentialNumbers(vector, targetSize);
for(unsigned i = 0; i < vector.GetSize(); ++i) for(unsigned i = 0; i < vector.GetSize(); ++i)
{ {
if(vector[i] != i) if(vector[i] != i)
{ {
return false; return false;
} }
} }
try try
{ {
vector[targetSize + 1] = 42; vector[targetSize + 1] = 42;
} }
catch(std::exception & e) catch(std::exception & e)
{ {
return true; return true;
} }
return false; return false;
} }
bool TestResize() bool TestResize()
{ {
Vector<unsigned> vector; Vector<unsigned> vector;
vector.Resize(2048u); vector.Resize(2048u);
FillWithSequentialNumbers(vector); FillWithSequentialNumbers(vector);
vector.Resize(vector.GetSize() / 2u); vector.Resize(vector.GetSize() / 2u);
for(unsigned i = 0; i < vector.GetSize(); ++i) for(unsigned i = 0; i < vector.GetSize(); ++i)
{ {
if(vector[i] != i) if(vector[i] != i)
{ {
return false; return false;
} }
} }
vector.Resize(vector.GetSize() * 16u); vector.Resize(vector.GetSize() * 16u);
return true; return true;
} }
bool TestReserve() bool TestReserve()
{ {
std::size_t const testSize = 8096ul; std::size_t const testSize = 8096ul;
Vector<unsigned> vector; Vector<unsigned> vector;
vector.Reserve(testSize); vector.Reserve(testSize);
if(vector.GetReserveSize() != testSize) if(vector.GetReserveSize() != testSize)
{ {
std::puts("[ERROR] Reserve size reported not equal to reserve size set."); std::puts("[ERROR] Reserve size reported not equal to reserve size set.");
return false; return false;
} }
for(std::size_t i = 0; i < testSize; ++i) for(std::size_t i = 0; i < testSize; ++i)
{ {
vector.Resize(i + 1ul); vector.Resize(i + 1ul);
vector[i] = i; vector[i] = i;
if(vector.GetReserveSize() != testSize) if(vector.GetReserveSize() != testSize)
{ {
std::puts("[ERROR] Reserve size changed during resize."); std::puts("[ERROR] Reserve size changed during resize.");
return false; return false;
} }
} }
for(std::size_t i = 0; i < testSize; ++i) for(std::size_t i = 0; i < testSize; ++i)
{ {
if(vector[i] != i) if(vector[i] != i)
{ {
return false; return false;
} }
} }
return true; return true;
} }
int main() int main()
{ {
Test::Execute(TestInsertion, "Insertion test"); Test::Execute(TestInsertion, "Insertion test");
Test::Execute(TestResize, "Resize test"); Test::Execute(TestResize, "Resize test");
Test::Execute(TestReserve, "Reserve test"); Test::Execute(TestReserve, "Reserve test");
return 0; return 0;
} }