diff --git a/include/foonathan/memory/memory_pool_collection.hpp b/include/foonathan/memory/memory_pool_collection.hpp index be7b7e5..15ebc1e 100644 --- a/include/foonathan/memory/memory_pool_collection.hpp +++ b/include/foonathan/memory/memory_pool_collection.hpp @@ -125,8 +125,8 @@ namespace foonathan /// \throws Anything thrown by the \concept{concept_blockallocator,BlockAllocator} if a growth is needed or a \ref bad_node_size exception if the node size is too big. void* allocate_node(std::size_t node_size) { - detail::check_allocation_size< - bad_node_size>(node_size, [&] { return max_node_size(); }, info()); + detail::check_allocation_size( + node_size, [&] { return max_node_size(); }, info()); auto& pool = pools_.get(node_size); if (pool.empty()) { @@ -169,8 +169,8 @@ namespace foonathan /// \c node_size must be valid \concept{concept_node,node size}. void* allocate_array(std::size_t count, std::size_t node_size) { - detail::check_allocation_size< - bad_node_size>(node_size, [&] { return max_node_size(); }, info()); + detail::check_allocation_size( + node_size, [&] { return max_node_size(); }, info()); auto& pool = pools_.get(node_size); @@ -425,8 +425,10 @@ namespace foonathan std::size_t alignment) { // node already checked + auto const aligned_size = + detail::round_up_to_multiple_of_alignment(size, alignment); detail::check_allocation_size( - alignment, [&] { return detail::alignment_for(size); }, state.info()); + aligned_size, [&] { return state.max_node_size(); }, state.info()); auto mem = state.allocate_node(size); state.on_allocate(size); return mem; @@ -439,8 +441,10 @@ namespace foonathan std::size_t alignment) { // node and array already checked + auto const aligned_size = + detail::round_up_to_multiple_of_alignment(size, alignment); detail::check_allocation_size( - alignment, [&] { return detail::alignment_for(size); }, state.info()); + aligned_size, [&] { return state.max_node_size(); }, state.info()); auto mem = state.allocate_array(count, size); state.on_allocate(count * size); return mem; diff --git a/test/memory_pool_collection.cpp b/test/memory_pool_collection.cpp index ad6e456..cf71013 100644 --- a/test/memory_pool_collection.cpp +++ b/test/memory_pool_collection.cpp @@ -50,6 +50,25 @@ TEST_CASE("memory_pool_collection") for (auto ptr : b) pool.deallocate_node(ptr, 5); } + SUBCASE("normal alloc/dealloc with traits") + { + std::vector a, b; + for (auto i = 0u; i != 5u; ++i) + { + a.push_back(allocator_traits::allocate_node(pool, 1, 8u)); + b.push_back(allocator_traits::allocate_node(pool, 5, 8u)); + } + REQUIRE(alloc.no_allocated() == 1u); + REQUIRE(pool.capacity_left() <= 4000u); + + std::shuffle(a.begin(), a.end(), std::mt19937{}); + std::shuffle(b.begin(), b.end(), std::mt19937{}); + + for (auto ptr : a) + allocator_traits::deallocate_node(pool, ptr, 1, 8); + for (auto ptr : b) + allocator_traits::deallocate_node(pool, ptr, 5, 8u); + } SUBCASE("single array alloc") { auto memory = pool.allocate_array(4, 4); @@ -75,6 +94,22 @@ TEST_CASE("memory_pool_collection") for (auto ptr : b) pool.deallocate_array(ptr, 5, 5); } + SUBCASE("array alloc/dealloc with traits") + { + std::vector a; + for (auto i = 0u; i != 5u; ++i) + { + a.push_back(allocator_traits::allocate_array(pool, 5, 5, 8u)); + REQUIRE(a.back()); + } + REQUIRE(alloc.no_allocated() == 1u); + REQUIRE(pool.capacity_left() <= 4000u); + + std::shuffle(a.begin(), a.end(), std::mt19937{}); + + for (auto ptr : a) + allocator_traits::deallocate_array(pool, ptr, 5, 5, 8u); + } SUBCASE("multiple block alloc/dealloc") { std::vector a, b;