diff --git a/include/gp/algorithm/tmp_manip.hpp b/include/gp/algorithm/tmp_manip.hpp index 80af38f..058c8e8 100644 --- a/include/gp/algorithm/tmp_manip.hpp +++ b/include/gp/algorithm/tmp_manip.hpp @@ -202,7 +202,7 @@ namespace gp{ typedef std::true_type yes; typedef std::false_type no; - template struct SFINAE{}; + template struct SFINAE{}; template static yes test(SFINAE*); @@ -219,7 +219,7 @@ namespace gp{ typedef std::true_type yes; typedef std::false_type no; - template struct SFINAE{}; + template struct SFINAE{}; template static yes test(SFINAE*); diff --git a/include/gp/allocator/arena.hpp b/include/gp/allocator/arena.hpp index 6fd38cf..118a2bd 100644 --- a/include/gp/allocator/arena.hpp +++ b/include/gp/allocator/arena.hpp @@ -7,7 +7,7 @@ namespace gp{ - template + template class arena{ page_allocator allocator; gp::buffer data; @@ -20,18 +20,20 @@ namespace gp{ ,data(gp::buffer(nullptr,nullptr)) {} - template::value,int>::type> arena(size_t sz) :last(0) ,count(0) ,data(nullptr,nullptr) { - if(sz!=0) + if constexpr (gp::has_allocator_interface::value) { - auto v=allocator.allocate(sz); - if(v!=nullptr) + if(sz!=0) { - data=gp::buffer(reinterpret_cast(v),reinterpret_cast(v)+sz); + auto v=allocator.allocate(sz); + if(v!=nullptr) + { + data=gp::buffer(reinterpret_cast(v),reinterpret_cast(v)+sz); + } } } } diff --git a/include/gp/ring_list.hpp b/include/gp/ring_list.hpp index 37a98e8..62b24b6 100644 --- a/include/gp/ring_list.hpp +++ b/include/gp/ring_list.hpp @@ -95,13 +95,22 @@ namespace gp { , alloc{_alloc} {} + ring_list(allocator& _alloc) + : any_node{nullptr} + , sz{0} + , alloc{_alloc} + {} + template bool insert(Args&&... elem) { allocator& used_allocator = alloc; - void* mem = used_allocator.allocate(sizeof(V)); + void* mem; + [[unlikely]] if( + nullptr == (mem = used_allocator.allocate(sizeof(V))) + ) return false; T* p = new(mem) V(elem...); node* to_insert = nullptr; - if( + [[unlikely]] if( nullptr == (to_insert = reinterpret_cast(used_allocator.allocate(sizeof(node)))) ) return false; to_insert = new(to_insert) node(p); diff --git a/tests/gp_test.cpp b/tests/gp_test.cpp index 8b15735..c52824f 100644 --- a/tests/gp_test.cpp +++ b/tests/gp_test.cpp @@ -3,6 +3,7 @@ #include "gp/array.hpp" #include "gp/indexed_array.hpp" #include "gp/allocator/aggregator.hpp" +#include "gp/allocator/arena.hpp" #include "gp/allocator/buddy.hpp" #include "gp/allocator/dummy.hpp" #include "gp/algorithm/repeat.hpp" @@ -414,6 +415,35 @@ struct aggregator_test : public test_scaffold { } auto duration = std::chrono::steady_clock::now() - start; } + void* a = allocator.allocate(8); + gp_config::assertion(allocator.try_reallocate(a, 16) == false, "could reallocate? was it implemented?"); + gp_config::assertion(allocator.deallocate(nullptr) == false, "error, could free an invalid pointer"); + allocator.deallocate(a); + { + gp::ring_list list{allocator}; + list.insert(8); + list.insert(16); + list.insert(32); + } + { + gp::array work_array; + gp::arena<> alloc_work(work_array.begin().data, work_array.size()); + gp::ring_list, false> list{alloc_work}; + gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator"); + gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator"); + gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator"); + } + { + gp::array once_array; + gp::arena<> alloc_once(once_array.begin().data, once_array.size()); + gp::ring_list, false> list{alloc_once}; + gp_config::assertion(list.insert(8) == false, "could allocate in list with insufficient allocator"); + } + { + gp::arena<> alloc_none(nullptr, 0); + gp::ring_list, false> list{alloc_none}; + gp_config::assertion(list.insert(8) == false, "could allocate in list with fake allocator"); + } return res; } };