diff --git a/include/duckhandy/alignment.hpp b/include/duckhandy/alignment.hpp deleted file mode 100644 index aa7f610..0000000 --- a/include/duckhandy/alignment.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2016-2025 Michele Santullo - * This file is part of "duckhandy". - * - * "duckhandy" 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. - * - * "duckhandy" 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 "duckhandy". If not, see . - */ - -#ifndef id99DC0F782D0F4907A7768E8743A8BE74 -#define id99DC0F782D0F4907A7768E8743A8BE74 - -#include -#include -#include - -namespace dhandy { -template -concept is_pow_of_two = static_cast(V and not(V bitand (V - 1u))); - -template -requires is_pow_of_two -constexpr T align_to (T v) { - return (v + V-1) & ~(T{V-1}); -} - -template -requires is_pow_of_two -constexpr T padding_to (T v) { - return (-v) & (V-1); -} - -template -requires is_pow_of_two -constexpr T* align_ptr_to (T* ptr, std::size_t add) { - return reinterpret_cast(align_to(reinterpret_cast(ptr) + add)); -} - -} //namespace dhandy -#endif diff --git a/include/duckhandy/implem/tree_iterator.inl b/include/duckhandy/implem/tree_iterator.inl deleted file mode 100644 index eb2f61b..0000000 --- a/include/duckhandy/implem/tree_iterator.inl +++ /dev/null @@ -1,252 +0,0 @@ -/* Copyright 2016-2024 Michele Santullo - * This file is part of "duckhandy". - * - * "duckhandy" 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. - * - * "duckhandy" 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 "duckhandy". If not, see . - */ - -namespace dhandy { - namespace implem { - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - bool TreeIterator_base

::Exhausted() const { - return m_stack.empty(); - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - TreeIterator_base

::TreeIterator_base (const TreeIterator_base& parOther) : - m_stack(parOther.m_stack) - { - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - template - TreeIterator_base

::TreeIterator_base (const TreeIterator_base& parOther) { - typename TreeIterator_base::StackType otherStackCopy(parOther.m_stack); - std::vector

localCopy; - localCopy.reserve(parOther.m_stack.size()); - while (not otherStackCopy.empty()) { - P convertedItem = otherStackCopy.top(); - localCopy.push_back(convertedItem); - otherStackCopy.pop(); - } - m_stack.reserve(parOther.m_stack.capacity()); - for (typename std::vector

::reverse_iterator itRev = localCopy.rbegin(), itRevEnd = localCopy.rend(); itRev != itRevEnd; ++itRev) { - assert(m_stack.capacity() > m_stack.size()); - m_stack.push(*itRev); - } - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - typename TreeIterator_const_layer::reference TreeIterator_const_layer::operator* () { - assert(not this->Exhausted()); - return this->m_stack.top()->content; - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - typename TreeIterator_const_layer::const_reference TreeIterator_const_layer::operator* () const { - assert(not this->Exhausted()); - return this->m_stack.top()->content; - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - typename TreeIterator_const_layer::pointer TreeIterator_const_layer::operator-> () { - assert(not this->Exhausted()); - return &this->m_stack.top()->content; - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - typename TreeIterator_const_layer::const_pointer TreeIterator_const_layer::operator-> () const { - assert(not this->Exhausted()); - return &this->m_stack.top()->content; - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - N* TreeIterator_const_layer::GetPointer() { - assert(not this->Exhausted()); - return this->m_stack.top(); - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - const N* TreeIterator_const_layer::GetPointer() const { - assert(not this->Exhausted()); - return this->m_stack.top(); - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - typename TreeIterator_const_layer::const_reference TreeIterator_const_layer::operator* () const { - assert(not this->Exhausted()); - return this->m_stack.top()->content; - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - typename TreeIterator_const_layer::const_pointer TreeIterator_const_layer::operator-> () const { - assert(not this->Exhausted()); - return &this->m_stack.top()->content; - } - - ///--------------------------------------------------------------------- - ///--------------------------------------------------------------------- - template - const N* TreeIterator_const_layer::GetPointer() const { - assert(not this->Exhausted()); - return this->m_stack.top(); - } - } //namespace implem - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - TreeIterator::TreeIterator() { - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - TreeIterator::TreeIterator (const TreeIterator& parOther) : - parent_type(parOther) - { - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - template - TreeIterator::TreeIterator (const TreeIterator& parOther) : - parent_type(parOther) - { - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - template - TreeIterator::TreeIterator (S parCopyStackBottomUp, size_type parStackLen, size_type parMaxDepthHint) { - assert(parStackLen > 0); - this->m_stack.reserve(std::max(parStackLen, parMaxDepthHint)); - typename StackType::value_type prevNode = *parCopyStackBottomUp; - ++parCopyStackBottomUp; - this->m_stack.push(prevNode); - - for (size_type z = 1; z < parStackLen; ++z) { - typename StackType::value_type currNode = *parCopyStackBottomUp; - if (prevNode->left == currNode) { - assert(this->m_stack.capacity() > this->m_stack.size()); - this->m_stack.push(currNode); - } - else { - //If you get this assertion make sure the iterator you are - //passing in is reversed (ie: from leaf to root) - assert(currNode == prevNode->right); - } - - prevNode = currNode; - ++parCopyStackBottomUp; - } - assert(not this->Exhausted()); - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - TreeIterator::TreeIterator (NodeTypePointer parRoot, size_type parMaxDepthHint) { - if (parMaxDepthHint > 0) - this->m_stack.reserve(parMaxDepthHint); - RecurseLeft(parRoot); - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - TreeIterator::~TreeIterator() { - } - - ///------------------------------------------------------------------------- - ///Post-increment - ///------------------------------------------------------------------------- - template - TreeIterator TreeIterator::operator++ (int) { - assert(not this->Exhausted()); - TreeIterator retVal = *this; - ++(*this); - return retVal; - } - - ///------------------------------------------------------------------------- - ///Pre-increment - ///------------------------------------------------------------------------- - template - TreeIterator& TreeIterator::operator++() { - assert(not this->Exhausted()); - NodeTypePointer currNode = this->m_stack.top(); -#if defined(ASSERTIONSENABLED) - const size_type stackCapacity = this->m_stack.capacity(); -#endif - this->m_stack.pop(); -#if defined(ASSERTIONSENABLED) - //It shouldn't normally happen, but it's just to make sure - assert(stackCapacity == this->m_stack.capacity()); -#endif - RecurseLeft(currNode->right); - return *this; - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - const TreeIterator& TreeIterator::operator= (const TreeIterator& parOther) { - this->m_stack = parOther.m_stack; - assert(this->m_stack.capacity() >= parOther.m_stack.capacity()); - return *this; - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - bool TreeIterator::operator== (const TreeIterator& parOther) const { - return this->m_stack.size() == parOther.m_stack.size() and (this->m_stack.empty() or parOther.m_stack.top() == this->m_stack.top()); - } - - ///------------------------------------------------------------------------- - ///------------------------------------------------------------------------- - template - void TreeIterator::RecurseLeft (NodeTypePointer parFrom) { - NodeTypePointer currNode = parFrom; - while (NULL != currNode) { - assert(this->m_stack.capacity() > this->m_stack.size()); - this->m_stack.push(currNode); - currNode = currNode->left; - } - } -} //namespace dhandy diff --git a/include/duckhandy/small_object_allocator.hpp b/include/duckhandy/small_object_allocator.hpp deleted file mode 100644 index b3fe28b..0000000 --- a/include/duckhandy/small_object_allocator.hpp +++ /dev/null @@ -1,268 +0,0 @@ -/* Copyright 2016-2024 Michele Santullo - * This file is part of "duckhandy". - * - * "duckhandy" 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. - * - * "duckhandy" 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 "duckhandy". If not, see . - */ - -#ifndef idE77208CAFC79452DA12757DD0F6692D3 -#define idE77208CAFC79452DA12757DD0F6692D3 - -#include "alignment.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(NDEBUG) && !defined(DEBUG_SMALL_OBJECT_ALLOCATOR) -# define DEBUG_SMALL_OBJECT_ALLOCATOR -#endif - -#if defined(DEBUG_SMALL_OBJECT_ALLOCATOR) -# include "tiger_bt.hpp" -# include "lengthof.h" -#endif - -namespace dhandy { -namespace implem { -[[gnu::pure,gnu::always_inline]] -unsigned int ffs (unsigned int val) { return static_cast(::ffs(static_cast(val))); } - -[[gnu::pure,gnu::always_inline]] -unsigned int ffs (unsigned long val) { return static_cast(::ffsl(static_cast(val))); } - -[[gnu::pure,gnu::always_inline]] -unsigned int ffs (unsigned long long val) { return static_cast(::ffsll(static_cast(val))); } - -#if defined(DEBUG_SMALL_OBJECT_ALLOCATOR) -template typename A> -consteval std::uint32_t make_signature() { - return static_cast( - bt::tiger(__PRETTY_FUNCTION__, lengthof(__PRETTY_FUNCTION__), bt::TigerPaddingV2).a & 0xFFFFFFFF - ); -} -#endif -} //namespace implem - -template -struct AllocatorFunction { - std::unique_ptr operator()() { - return std::make_unique(); - } -}; - -template typename A=AllocatorFunction> -class SmallObjectAllocator { -public: - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef std::true_type propagate_on_container_move_assignment; - -private: - typedef std::uint_fast32_t uint_freelist_t; - typedef std::uint32_t index_t; - - struct TAndPtrFakeStruct { //only used for sizeof() - TAndPtrFakeStruct() = delete; - T t; -#if defined(DEBUG_SMALL_OBJECT_ALLOCATOR) - std::uint32_t signature; -#endif - index_t block_index; //index in a lookup table so that lookup[index-1]->next == owner - }; - - static constexpr std::uint32_t signature = implem::make_signature(); - static constexpr size_type size = sizeof(TAndPtrFakeStruct); - static constexpr size_type align = alignof(TAndPtrFakeStruct); - static constexpr size_type object_size = sizeof(T); //(size < sizeof(T*) ? sizeof(T*) : size); - static constexpr size_type object_align = alignof(T); //(align < alignof(T*) ? alignof(T*) : align); - static constexpr size_type block_ptr_offset = offsetof(TAndPtrFakeStruct, block); - -public: - static constexpr size_type objects_per_block = CHAR_BIT * sizeof(uint_freelist_t); - -private: - struct Block { - typedef typename std::aligned_storage::type raw_t; - - raw_t data[objects_per_block]; - std::unique_ptr next; - uint_freelist_t freelist{0}; - }; - -public: - - SmallObjectAllocator() = default; - ~SmallObjectAllocator() noexcept = default; - - [[nodiscard]] constexpr pointer allocate (size_type size); - //[[nodiscard]] constexpr std::allocation_result allocate_at_least (size_type size); - constexpr void deallocate (pointer ptr, size_type size); - - //template - //constexpr bool operator== (const allocator& rhs) noexcept; - - -private: - static index_t* fetch_block_index (Block::raw_t* in_ptr); - static void set_block_indices (Block* block, index_t new_index); - static void set_debug_signatures (Block* block); - - std::vector m_block_list; - std::unique_ptr m_head; - index_t m_prev_index; - index_t m_curr_index{0}; -}; - -template typename A> -constexpr auto SmallObjectAllocator::allocate (size_type size) -> pointer { - assert(object_size == size); -#if defined(NDEBUG) - static_cast(size); -#endif - - assert(0 == m_curr_index or m_curr_index <= m_block_list.size()); - assert(m_head or m_block_list.empty()); - if (!m_curr_index or !~m_block_list[m_curr_index-1]->freelist) { - A alloc_function{}; - auto new_block = alloc_function(); - set_debug_signatures(new_block.get()); - new_block->next = std::move(m_head); - m_head.swap(new_block); - m_block_list.push_back(m_head.get()); - m_prev_index = m_curr_index; - m_curr_index = static_cast(m_block_list.size()); - - if (m_head->next) - set_block_indices(m_head->next.get(), m_curr_index); - } - - Block*const block = m_block_list[m_curr_index-1]; - assert(block != nullptr); - const uint_freelist_t neg_freelist = static_cast(~block->freelist); - assert(neg_freelist != 0); - - const unsigned int object_num = implem::ffs(neg_freelist); - assert(object_num); - const unsigned int object_index = object_num - 1; - assert(object_index < objects_per_block); - constexpr uint_freelist_t one = 1; - block->freelist |= one << object_index; - - index_t* const index_ptr = fetch_block_index(block->data + object_index); - assert(index_ptr); - *index_ptr = m_prev_index; - return reinterpret_cast(block->data + object_index); -} - -template typename A> -constexpr void SmallObjectAllocator::deallocate (pointer ptr, size_type size) { - assert(object_size == size); - auto* const block_ptr = reinterpret_cast(ptr); - const index_t owner_prev_index = *fetch_block_index(block_ptr); - Block* const owner = (0 == owner_prev_index ? m_head.get() : m_block_list[owner_prev_index-1]->next.get()); - - assert(owner); - const auto flag_index = std::distance(owner->data, block_ptr); - assert(flag_index >= 0); - assert(flag_index < objects_per_block); - - constexpr uint_freelist_t one = 1; - const uint_freelist_t mask = one << flag_index; - assert((owner->freelist & mask) != 0); - owner->freelist &= ~mask; - - if (0 == owner->freelist) { - if (owner_prev_index) { - Block& prev = *m_block_list[owner_prev_index-1]; - auto found = std::find(m_block_list.begin(), m_block_list.end(), owner); - assert(m_block_list.end() != found); - it's all fucked up here, I can't delete the item because that would - invalidate all the subsequent indices. It means all blocks following - the one being deleted would have to get set_block_indices() invoked - on them which is insane so this whole approach is fucke' - - auto empty_block = std::move(prev.next); - assert(!prev.next); - prev.next = std::move(empty_block->next); - set_block_indices(prev.next.get(), owner_prev_index); - - } - else { - assert(m_block_list.empty()); - m_head.reset(); - m_curr_index = 0; - } - } -} - -template typename A> -auto SmallObjectAllocator::fetch_block_index (Block::raw_t* in_ptr) -> index_t* { - assert(in_ptr); - - char* ptr = reinterpret_cast(in_ptr); -#if defined(DEBUG_SMALL_OBJECT_ALLOCATOR) - ptr = align_ptr_to(ptr, object_size); - { - std::uint32_t read_signature; - std::memcpy(&read_signature, ptr, sizeof(signature)); - assert(signature == read_signature); - } - ptr = align_ptr_to(ptr, sizeof(signature)); -#else - ptr = align_ptr_to(ptr, object_size); -#endif - - index_t* const retval = reinterpret_cast(ptr); - return retval; -} - -template typename A> -void SmallObjectAllocator::set_block_indices (Block* block, index_t new_index) { - uint_freelist_t flag = 1; - for (unsigned int z = 0; z < objects_per_block; ++z, flag<<=1) { - if (flag & block->freelist) { - index_t* const dst_index = fetch_block_index(block->data + z); - assert(dst_index); - *dst_index = new_index; - } - } -} - -template typename A> -void SmallObjectAllocator::set_debug_signatures (Block* block) { -#if defined(DEBUG_SMALL_OBJECT_ALLOCATOR) - const auto sig = signature; - for (unsigned int z = 0; z < objects_per_block; ++z) { - std::memcpy(align_ptr_to(block->data + z, object_size), &sig, sizeof(signature)); - } -#else - static_cast(block); -#endif -} -} //namespace dhandy - -#endif diff --git a/include/duckhandy/tree_iterator.hpp b/include/duckhandy/tree_iterator.hpp deleted file mode 100644 index 40b3e41..0000000 --- a/include/duckhandy/tree_iterator.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright 2016-2024 Michele Santullo - * This file is part of "duckhandy". - * - * "duckhandy" 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. - * - * "duckhandy" 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 "duckhandy". If not, see . - */ - -#ifndef id6109D5EDE99D43C4909F084A231BF2C2 -#define id6109D5EDE99D43C4909F084A231BF2C2 - -#include -#include -#include -#include -#include - -namespace dhandy { - namespace implem { - template - class TreeIteratorStack : public std::stack> { - public: - void reserve (std::size_t size) { - std::stack>::c.reserve(size); - } - - std::size_t capacity() const { - return std::stack>::c.capacity(); - } - private: - }; - - template - class TreeIterator_base { - template friend class TreeIterator_base; - public: - explicit TreeIterator_base ( void ) {} - TreeIterator_base ( const TreeIterator_base& parOther ); - template - explicit TreeIterator_base ( const TreeIterator_base& parOther ); - ~TreeIterator_base ( void ) {} - protected: - typedef TreeIteratorStack

StackType; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - bool Exhausted ( void ) const; - StackType m_stack; - }; - - template - class TreeIterator_const_layer; - template - class TreeIterator_const_layer : protected TreeIterator_base { - template friend class TreeIterator_const_layer; - typedef TreeIterator_base parent_type; - public: - typedef const T* pointer; - typedef const T* const_pointer; - typedef const T& reference; - typedef const T& const_reference; - typedef typename parent_type::size_type size_type; - typedef typename parent_type::difference_type difference_type; - typedef N NodeType; - typedef const N* NodeTypePointer; - enum { IS_CONST = 1 }; - TreeIterator_const_layer ( void ) {} - TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} - template - explicit TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} - const_reference operator* ( void ) const; - const_pointer operator-> ( void ) const; - const N* GetPointer ( void ) const; - protected: - typedef typename parent_type::StackType StackType; - }; - template - class TreeIterator_const_layer : protected TreeIterator_base { - template friend class TreeIterator_const_layer; - typedef TreeIterator_base parent_type; - public: - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef typename parent_type::size_type size_type; - typedef typename parent_type::difference_type difference_type; - typedef N NodeType; - typedef N* NodeTypePointer; - enum { IS_CONST = 0 }; - TreeIterator_const_layer ( void ) {} - TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} - template - explicit TreeIterator_const_layer ( const TreeIterator_const_layer& parOther ) : parent_type(parOther) {} - reference operator* ( void ); - const_reference operator* ( void ) const; - pointer operator-> ( void ); - const_pointer operator-> ( void ) const; - const N* GetPointer ( void ) const; - N* GetPointer ( void ); - protected: - typedef typename parent_type::StackType StackType; - }; - } //namespace implem - - template - class TreeIterator : public implem::TreeIterator_const_layer::value> { - typedef implem::TreeIterator_const_layer::value> parent_type; - typedef typename parent_type::NodeTypePointer NodeTypePointer; - typedef typename parent_type::NodeType NodeType; - typedef typename parent_type::StackType StackType; - public: - typedef T value_type; - typedef std::forward_iterator_tag iterator_category; - typedef typename parent_type::difference_type difference_type; - typedef typename parent_type::size_type size_type; - typedef typename parent_type::pointer pointer; - typedef typename parent_type::const_pointer const_pointer; - typedef typename parent_type::reference reference; - typedef typename parent_type::const_reference const_reference; - - TreeIterator ( void ); - TreeIterator ( const TreeIterator& parOther ); - TreeIterator ( NodeTypePointer parRoot, size_type parMaxDepthHint ); - template - TreeIterator ( S parCopyStackBottomUp, size_type parStackLen, size_type parMaxDepthHint ); - template - TreeIterator ( const TreeIterator& parOther ); - ~TreeIterator ( void ); - - const TreeIterator& operator= ( const TreeIterator& parOther ); - bool operator== ( const TreeIterator& parOther ) const; - bool operator!= ( const TreeIterator& parOther ) const { return not (*this == parOther); } - TreeIterator& operator++ ( void ); //pre - TreeIterator operator++ ( int ); //post - - private: - void RecurseLeft ( NodeTypePointer parFrom ); - }; -} //namespace dhandy - -#include "implem/tree_iterator.inl" - -#endif diff --git a/test/unit/meson.build b/test/unit/meson.build index 9fa0534..7777af0 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -10,8 +10,6 @@ unit_test_prog = executable(meson.project_name(), 'version_test.cpp', 'tiger_test.cpp', 'infix_iterator.cpp', - 'tree_iterator_test.cpp', - 'small_object_allocator_test.cpp', install: false, dependencies: [sprout_dep, catch2_dep], include_directories: [public_incl], diff --git a/test/unit/small_object_allocator_test.cpp b/test/unit/small_object_allocator_test.cpp deleted file mode 100644 index a7258ab..0000000 --- a/test/unit/small_object_allocator_test.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2016-2024 Michele Santullo - * This file is part of "duckhandy". - * - * "duckhandy" 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. - * - * "duckhandy" 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 "duckhandy". If not, see . - */ - -#include "catch2/catch_test_macros.hpp" -#include "duckhandy/small_object_allocator.hpp" -#include - -namespace { -static const void* g_alloc_last{nullptr}; -static std::size_t g_alloc_count{0}; - -template -struct TestAlloc { - std::unique_ptr operator()() { - auto ret = std::make_unique(); - g_alloc_last = ret.get(); - ++g_alloc_count; - return ret; - } -}; -} //unnamed namespace - -TEST_CASE("Check SmallObjectAllocator", "[SmallObjectAllocator][containers][memory][allocators]") { - dhandy::SmallObjectAllocator soa; - CHECK(g_alloc_last == nullptr); - CHECK(g_alloc_count == 0u); - - int* const int01 = soa.allocate(sizeof(int)); - const void* old_block = g_alloc_last; - REQUIRE(int01 != nullptr); - CHECK(g_alloc_last != nullptr); - CHECK(g_alloc_count == 1); - - int* const int02 = soa.allocate(sizeof(int)); - REQUIRE(int02 != nullptr); - CHECK(int01 != int02); - CHECK(g_alloc_last == old_block); - CHECK(g_alloc_count == 1); - - int* prev_int = int02; - for (std::size_t z = 2; z < dhandy::SmallObjectAllocator::objects_per_block; ++z) { - int* const new_int = soa.allocate(sizeof(int)); - REQUIRE(new_int != nullptr); - CHECK(new_int != int01); - CHECK(new_int != prev_int); - prev_int = new_int; - CHECK(g_alloc_last == old_block); - CHECK(g_alloc_count == 1); - CHECK(reinterpret_cast(new_int) % alignof(int) == 0); - } - - int* const int03 = soa.allocate(sizeof(int)); - REQUIRE(int03 != nullptr); - CHECK(int03 != int02); - CHECK(int03 != int01); - CHECK(g_alloc_last != old_block); - old_block = g_alloc_last; - CHECK(g_alloc_count == 2); - - soa.deallocate(int02, sizeof(int)); -} diff --git a/test/unit/tree_iterator_test.cpp b/test/unit/tree_iterator_test.cpp deleted file mode 100644 index b0533a4..0000000 --- a/test/unit/tree_iterator_test.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright 2016-2024 Michele Santullo - * This file is part of "duckhandy". - * - * "duckhandy" 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. - * - * "duckhandy" 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 "duckhandy". If not, see . - */ - -#include "catch2/catch_test_macros.hpp" -#include "duckhandy/tree_iterator.hpp" - -namespace { - -enum Letters : unsigned int { - A = 'a', B, C, D, E, F, G, H, I -}; - -struct TestNode { - TestNode (unsigned int val) : content(val) {} - TestNode* left{nullptr}, *right{nullptr}; - unsigned int content{0}; -}; -} //unnamed namespace - -TEST_CASE("Check TreeIterator", "[TreeIterator][containers][iterator]") { - typedef dhandy::TreeIterator TestIterator; - - TestIterator empty; - - { - TestNode root{0xDEADBEEFu}; - TestIterator it{&root, 1}; - CHECK(*it == 0xDEADBEEFu); - - ++it; - CHECK(it == empty); - } - - { - TestNode root{A}; - TestNode l{B}, ll{C}, lr{D}; - TestNode r{E}, rl{F}, rr{G}, rll{H}, rrr{I}; - - root.left = &l; - root.right = &r; - l.left = ≪ - l.right = &lr; - r.left = &rl; - r.right = &rr; - rl.left = &rll; - rr.right = &rrr; - - TestIterator it{&root, 4}; - CHECK(*it == C); //ll - ++it; - CHECK(*it == B); //l - it++; - CHECK(*it == D); //lr - it++; - CHECK(*it == A); //root - ++it; - CHECK(*it == H); //rll - it++; - CHECK(*it == F); //rl - it++; - CHECK(*it == E); //r - ++it; - CHECK(*it == G); //rr - ++it; - CHECK(*it == I); //rrr - CHECK(it != empty); - it++; - CHECK(it == empty); - } - - { - TestNode root{A}; - TestNode l{B}, ll{C}, lll{D}, llll{E}, lllll{F}; - root.left = &l; - l.left = ≪ - ll.left = &lll; - lll.left = &llll; - llll.left = &lllll; - - TestIterator it{&root, 6}; - CHECK(it != empty); - CHECK(*it == F); - ++it; - CHECK(*it == E); - ++it; - CHECK(*it == D); - ++it; - CHECK(*it == C); - ++it; - CHECK(*it == B); - ++it; - CHECK(*it == A); - ++it; - CHECK(it == empty); - } - - { - TestNode root{A}; - TestNode r{B}, rr{C}, rrr{D}, rrrr{E}, rrrrr{F}; - root.right = &r; - r.right = &rr; - rr.right = &rrr; - rrr.right = &rrrr; - rrrr.right = &rrrrr; - - TestIterator it{&root, 6}; - CHECK(it != empty); - CHECK(*it == A); - ++it; - CHECK(*it == B); - ++it; - CHECK(*it == C); - ++it; - CHECK(*it == D); - ++it; - CHECK(*it == E); - ++it; - CHECK(*it == F); - ++it; - CHECK(it == empty); - } -}