From 4268ff3016496ac28ecad7327b6c16a8a0ed0d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Tue, 21 Feb 2017 10:51:07 +0100 Subject: [PATCH 01/13] Update submodule Fixes #10. --- cmake/comp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/comp b/cmake/comp index 9d1a6fdb..cd142129 160000 --- a/cmake/comp +++ b/cmake/comp @@ -1 +1 @@ -Subproject commit 9d1a6fdb6cf2d9d88f280a8b893c23123bccd506 +Subproject commit cd142129e30f5b3e6c6d96310daf94242c0b03bf From 5eef7ffab64cd8ee2dec11168fa4dc73996e67a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sun, 10 Sep 2017 11:44:52 +0200 Subject: [PATCH 02/13] Enable C++11 on node size debugger --- src/CMakeLists.txt | 1 + test/CMakeLists.txt | 1 + tool/CMakeLists.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37dcc49b..1778d243 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,6 +88,7 @@ endif() add_library(foonathan_memory ${detail_header} ${header} ${src}) _foonathan_use_comp(foonathan_memory) +comp_target_features(foonathan_memory PRIVATE CPP11) target_include_directories(foonathan_memory PUBLIC $ # for client in subdirectory $ # for generated files in build mode $ # for client in install mode diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 989503d9..bb1da72f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -49,6 +49,7 @@ set(tests segregator.cpp) add_executable(foonathan_memory_test ${tests}) +comp_target_features(foonathan_memory_test PUBLIC CPP11) target_link_libraries(foonathan_memory_test foonathan_memory) target_include_directories(foonathan_memory_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR} diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index 4905436b..5702f851 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(foonathan_memory_node_size_debugger test_types.hpp node_size_debugger.hpp node_size_debugger.cpp) _foonathan_use_comp(foonathan_memory_node_size_debugger) +comp_target_features(foonathan_memory_node_size_debugger PUBLIC CPP11) target_compile_definitions(foonathan_memory_node_size_debugger PUBLIC VERSION="${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}") set_target_properties(foonathan_memory_node_size_debugger PROPERTIES OUTPUT_NAME nodesize_dbg) From 015036d5d47a3d47451d0740727fd9a5af4eeb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sun, 10 Sep 2017 12:01:04 +0200 Subject: [PATCH 03/13] Fix test case --- test/detail/free_list.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/detail/free_list.cpp b/test/detail/free_list.cpp index 0c2378fe..f0f497e7 100644 --- a/test/detail/free_list.cpp +++ b/test/detail/free_list.cpp @@ -112,11 +112,15 @@ TEST_CASE("free_memory_list", "[detail][pool]") { static_allocator_storage<1024> memory; check_list(list, &memory, 1024); + + check_move(list); } SECTION("uneven insert") { static_allocator_storage<1023> memory; // not dividable check_list(list, &memory, 1023); + + check_move(list); } SECTION("multiple insert") { @@ -126,8 +130,9 @@ TEST_CASE("free_memory_list", "[detail][pool]") check_list(list, &a, 1024); check_list(list, &b, 100); check_list(list, &c, 1337); + + check_move(list); } - check_move(list); } void use_list_array(ordered_free_memory_list& list) @@ -173,12 +178,16 @@ TEST_CASE("ordered_free_memory_list", "[detail][pool]") static_allocator_storage<1024> memory; check_list(list, &memory, 1024); use_list_array(list); + + check_move(list); } SECTION("uneven insert") { static_allocator_storage<1023> memory; // not dividable check_list(list, &memory, 1023); use_list_array(list); + + check_move(list); } SECTION("multiple insert") { @@ -191,8 +200,9 @@ TEST_CASE("ordered_free_memory_list", "[detail][pool]") use_list_array(list); check_list(list, &c, 1337); use_list_array(list); + + check_move(list); } - check_move(list); } TEST_CASE("small_free_memory_list", "[detail][pool]") @@ -206,16 +216,22 @@ TEST_CASE("small_free_memory_list", "[detail][pool]") { static_allocator_storage<1024> memory; check_list(list, &memory, 1024); + + check_move(list); } SECTION("uneven insert") { static_allocator_storage<1023> memory; // not dividable check_list(list, &memory, 1023); + + check_move(list); } SECTION("big insert") { static_allocator_storage<4096> memory; // should use multiple chunks check_list(list, &memory, 4096); + + check_move(list); } SECTION("multiple insert") { @@ -225,6 +241,7 @@ TEST_CASE("small_free_memory_list", "[detail][pool]") check_list(list, &a, 1024); check_list(list, &b, 100); check_list(list, &c, 1337); + + check_move(list); } - check_move(list); } From 3fe9bd87bc9e3b65efcda9df7ab72276ecb5ef07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sun, 10 Sep 2017 12:09:07 +0200 Subject: [PATCH 04/13] Add static_assert when trying to default construct a stateful allocator Fixes #13. --- include/foonathan/memory/std_allocator.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/foonathan/memory/std_allocator.hpp b/include/foonathan/memory/std_allocator.hpp index 444fe432..54a0df2e 100644 --- a/include/foonathan/memory/std_allocator.hpp +++ b/include/foonathan/memory/std_allocator.hpp @@ -112,6 +112,8 @@ namespace foonathan /// \requires The \c RawAllocator type is stateless, otherwise the body of this function will not compile. std_allocator() FOONATHAN_NOEXCEPT : alloc_reference(allocator_type{}) { + static_assert(!alloc_reference::is_stateful::value, + "default constructor must not be used for stateful allocators"); } /// \effects Creates it from a reference to a \c RawAllocator. From 0d56eaea55682121fc888a02bfe0e74d5f95adbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sun, 10 Sep 2017 12:17:30 +0200 Subject: [PATCH 05/13] Make code Wshadow clean Fixes #14. --- include/foonathan/memory/error.hpp | 7 +++---- include/foonathan/memory/joint_allocator.hpp | 4 ++-- include/foonathan/memory/memory_arena.hpp | 5 ++--- include/foonathan/memory/memory_stack.hpp | 6 +++--- src/detail/small_free_list.cpp | 8 ++++---- test/default_allocator.cpp | 16 ++++++++-------- test/iteration_allocator.cpp | 6 +++--- test/joint_allocator.cpp | 4 ++-- test/memory_arena.cpp | 8 ++++---- test/memory_stack.cpp | 6 +++--- 10 files changed, 34 insertions(+), 36 deletions(-) diff --git a/include/foonathan/memory/error.hpp b/include/foonathan/memory/error.hpp index e1f08cbe..4b881707 100644 --- a/include/foonathan/memory/error.hpp +++ b/include/foonathan/memory/error.hpp @@ -35,10 +35,9 @@ namespace foonathan const void* allocator; /// \effects Creates it by giving it the name of the allocator and a pointer. - FOONATHAN_CONSTEXPR allocator_info(const char *name, - const void *allocator) FOONATHAN_NOEXCEPT - : name(name), - allocator(allocator) + FOONATHAN_CONSTEXPR allocator_info(const char* n, const void* alloc) FOONATHAN_NOEXCEPT + : name(n), + allocator(alloc) { } diff --git a/include/foonathan/memory/joint_allocator.hpp b/include/foonathan/memory/joint_allocator.hpp index 4b38c68e..e2635b88 100644 --- a/include/foonathan/memory/joint_allocator.hpp +++ b/include/foonathan/memory/joint_allocator.hpp @@ -102,7 +102,7 @@ namespace foonathan /// \ingroup memory allocator class joint { - joint(std::size_t capacity) FOONATHAN_NOEXCEPT : capacity(capacity) + joint(std::size_t cap) FOONATHAN_NOEXCEPT : capacity(cap) { } @@ -122,7 +122,7 @@ namespace foonathan { std::size_t size; - explicit joint_size(std::size_t size) FOONATHAN_NOEXCEPT : size(size) + explicit joint_size(std::size_t s) FOONATHAN_NOEXCEPT : size(s) { } }; diff --git a/include/foonathan/memory/memory_arena.hpp b/include/foonathan/memory/memory_arena.hpp index da738ef3..84c15cd5 100644 --- a/include/foonathan/memory/memory_arena.hpp +++ b/include/foonathan/memory/memory_arena.hpp @@ -38,7 +38,7 @@ namespace foonathan } /// \effects Creates a memory block from a given starting address and size. - memory_block(void* mem, std::size_t size) FOONATHAN_NOEXCEPT : memory(mem), size(size) + memory_block(void* mem, std::size_t s) FOONATHAN_NOEXCEPT : memory(mem), size(s) { } @@ -169,8 +169,7 @@ namespace foonathan node* prev; std::size_t usable_size; - node(node* prev, std::size_t size) FOONATHAN_NOEXCEPT : prev(prev), - usable_size(size) + node(node* p, std::size_t size) FOONATHAN_NOEXCEPT : prev(p), usable_size(size) { } diff --git a/include/foonathan/memory/memory_stack.hpp b/include/foonathan/memory/memory_stack.hpp index 9ade2f17..440c7db3 100644 --- a/include/foonathan/memory/memory_stack.hpp +++ b/include/foonathan/memory/memory_stack.hpp @@ -35,9 +35,9 @@ namespace foonathan const char* end; stack_marker(std::size_t i, const detail::fixed_memory_stack& s, - const char* end) FOONATHAN_NOEXCEPT : index(i), - top(s.top()), - end(end) + const char* e) FOONATHAN_NOEXCEPT : index(i), + top(s.top()), + end(e) { } diff --git a/src/detail/small_free_list.cpp b/src/detail/small_free_list.cpp index 6f0fbc59..5095696b 100644 --- a/src/detail/small_free_list.cpp +++ b/src/detail/small_free_list.cpp @@ -348,7 +348,7 @@ chunk* small_free_memory_list::find_chunk_impl(std::size_t n) FOONATHAN_NOEXCEPT { if (auto c = make_chunk(alloc_chunk_, n)) return c; - else if (auto c = make_chunk(dealloc_chunk_, n)) + else if ((c = make_chunk(dealloc_chunk_, n)) != nullptr) return c; auto cur_forward = alloc_chunk_->next; @@ -358,7 +358,7 @@ chunk* small_free_memory_list::find_chunk_impl(std::size_t n) FOONATHAN_NOEXCEPT { if (auto c = make_chunk(cur_forward, n)) return c; - else if (auto c = make_chunk(cur_backward, n)) + else if ((c = make_chunk(cur_backward, n)) != nullptr) return c; cur_forward = cur_forward->next; @@ -379,7 +379,7 @@ chunk* small_free_memory_list::find_chunk_impl(unsigned char* node, chunk_base* { if (auto c = from_chunk(first, node, actual_size)) return c; - else if (auto c = from_chunk(last, node, actual_size)) + else if ((c = from_chunk(last, node, actual_size)) != nullptr) return c; first = first->next; @@ -394,7 +394,7 @@ chunk* small_free_memory_list::find_chunk_impl(unsigned char* node) FOONATHAN_NO if (auto c = from_chunk(dealloc_chunk_, node, actual_size)) return c; - else if (auto c = from_chunk(alloc_chunk_, node, actual_size)) + else if ((c = from_chunk(alloc_chunk_, node, actual_size)) != nullptr) return c; else if (less(dealloc_chunk_, node)) { diff --git a/test/default_allocator.cpp b/test/default_allocator.cpp index e7f1c2ce..f9235601 100644 --- a/test/default_allocator.cpp +++ b/test/default_allocator.cpp @@ -23,21 +23,21 @@ void check_default_allocator(Allocator& alloc, std::size_t def_alignment = detai for (std::size_t i = 0u; i != 10u; ++i) { - auto ptr = alloc.allocate_node(i, 1); - REQUIRE(detail::is_aligned(ptr, def_alignment)); - alloc.deallocate_node(ptr, i, 1); + auto node = alloc.allocate_node(i, 1); + REQUIRE(detail::is_aligned(node, def_alignment)); + alloc.deallocate_node(node, i, 1); } - std::vector ptrs; + std::vector nodes; for (std::size_t i = 0u; i != 10u; ++i) { - auto ptr = alloc.allocate_node(i, 1); - REQUIRE(detail::is_aligned(ptr, def_alignment)); - ptrs.push_back(ptr); + auto node = alloc.allocate_node(i, 1); + REQUIRE(detail::is_aligned(node, def_alignment)); + nodes.push_back(node); } for (std::size_t i = 0u; i != 10u; ++i) - alloc.deallocate_node(ptrs[i], i, 1); + alloc.deallocate_node(nodes[i], i, 1); } TEST_CASE("heap_allocator", "[default_allocator]") diff --git a/test/iteration_allocator.cpp b/test/iteration_allocator.cpp index 21125024..adcfb175 100644 --- a/test/iteration_allocator.cpp +++ b/test/iteration_allocator.cpp @@ -21,9 +21,9 @@ TEST_CASE("iteration_allocator", "[stack]") REQUIRE(iter_alloc.capacity_left(0u) == 50); REQUIRE(iter_alloc.capacity_left(1u) == 50); - auto mem = iter_alloc.allocate(10, 1); + iter_alloc.allocate(10, 1); REQUIRE(iter_alloc.capacity_left() < 50); - auto mem2 = iter_alloc.allocate(4, 4); + iter_alloc.allocate(4, 4); REQUIRE(iter_alloc.capacity_left() < 50); REQUIRE(iter_alloc.capacity_left(1u) == 50); @@ -32,7 +32,7 @@ TEST_CASE("iteration_allocator", "[stack]") REQUIRE(iter_alloc.capacity_left() == 50); REQUIRE(iter_alloc.capacity_left(0u) < 50); - mem = iter_alloc.allocate(10, 1); + iter_alloc.allocate(10, 1); REQUIRE(iter_alloc.capacity_left() < 50); iter_alloc.next_iteration(); diff --git a/test/joint_allocator.cpp b/test/joint_allocator.cpp index 6d5c7c89..4e484a75 100644 --- a/test/joint_allocator.cpp +++ b/test/joint_allocator.cpp @@ -184,8 +184,8 @@ TEST_CASE("joint_allocator", "[allocator]") vector vec; int value; - joint_test(joint tag, int value, std::size_t size) - : joint_type(tag), vec(*this), value(value) + joint_test(joint tag, int val, std::size_t size) + : joint_type(tag), vec(*this), value(val) { vec.reserve(size); vec.push_back(42); diff --git a/test/memory_arena.cpp b/test/memory_arena.cpp index d2951a9f..d3c6a8bd 100644 --- a/test/memory_arena.cpp +++ b/test/memory_arena.cpp @@ -40,10 +40,10 @@ TEST_CASE("detail::memory_block_stack", "[detail][arena]") REQUIRE(stack.empty()); REQUIRE(!other.empty()); - auto top = other.top(); - REQUIRE(top.memory >= static_cast(&memory)); - REQUIRE(top.size <= 1024); - REQUIRE(is_aligned(top.memory, max_alignment)); + auto other_top = other.top(); + REQUIRE(other_top.memory >= static_cast(&memory)); + REQUIRE(other_top.size <= 1024); + REQUIRE(is_aligned(other_top.memory, max_alignment)); } static_allocator_storage<1024> a, b, c; diff --git a/test/memory_stack.cpp b/test/memory_stack.cpp index 14021bbe..9bd9f36d 100644 --- a/test/memory_stack.cpp +++ b/test/memory_stack.cpp @@ -120,10 +120,10 @@ TEST_CASE("memory_stack", "[stack]") REQUIRE(unwind.will_unwind()); { - memory_stack_raii_unwind unwind(stack); + memory_stack_raii_unwind unwind2(stack); stack.allocate(10, 1); - unwind.release(); - REQUIRE(!unwind.will_unwind()); + unwind2.release(); + REQUIRE(!unwind2.will_unwind()); } REQUIRE(stack.top() > m); m = stack.top(); From 1b2fd51d1db5d5e2861e636c5f61ce817de51a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sun, 10 Sep 2017 12:19:36 +0200 Subject: [PATCH 06/13] Add license badge Fixes #12. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c967bd9..03fc2970 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # memory -[![Build Status](https://travis-ci.org/foonathan/memory.svg?branch=master)](https://travis-ci.org/foonathan/memory) [![Build status](https://ci.appveyor.com/api/projects/status/ef654yqyoqgvl472/branch/master?svg=true)](https://ci.appveyor.com/project/foonathan/memory/branch/master) +[![Build Status](https://travis-ci.org/foonathan/memory.svg?branch=master)](https://travis-ci.org/foonathan/memory) [![Build status](https://ci.appveyor.com/api/projects/status/ef654yqyoqgvl472/branch/master?svg=true)](https://ci.appveyor.com/project/foonathan/memory/branch/master) [![License: Zlib](https://img.shields.io/badge/License-Zlib-lightgrey.svg)](https://opensource.org/licenses/Zlib) The C++ STL allocator model has various flaws. For example, they are fixed to a certain type, because they are almost necessarily required to be templates. So you can't easily share a single allocator for multiple types. In addition, you can only get a copy from the containers and not the original allocator object. At least with C++11 they are allowed to be stateful and so can be made object not instance based. But still, the model has many flaws. Over the course of the years many solutions have been proposed. for example [EASTL]. This library is another. But instead of trying to change the STL, it works with the current implementation. From 74ad4f1b417beaf273d5ed1689eac166153f60a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Mon, 30 Oct 2017 10:00:38 +0100 Subject: [PATCH 07/13] Workaround old GCC assuming default constructible allocators in string --- include/foonathan/memory/std_allocator.hpp | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/include/foonathan/memory/std_allocator.hpp b/include/foonathan/memory/std_allocator.hpp index 54a0df2e..bd87b82d 100644 --- a/include/foonathan/memory/std_allocator.hpp +++ b/include/foonathan/memory/std_allocator.hpp @@ -112,8 +112,12 @@ namespace foonathan /// \requires The \c RawAllocator type is stateless, otherwise the body of this function will not compile. std_allocator() FOONATHAN_NOEXCEPT : alloc_reference(allocator_type{}) { +#if !defined(__GNUC__) || (defined(_GLIBCXX_USE_CXX11_ABI) && _GLIBCXX_USE_CXX11_ABI != 0) + // std::string requires default constructor for the small string optimization when using gcc's old ABI + // so don't assert then to allow joint allocator static_assert(!alloc_reference::is_stateful::value, "default constructor must not be used for stateful allocators"); +#endif } /// \effects Creates it from a reference to a \c RawAllocator. @@ -123,13 +127,14 @@ namespace foonathan /// If the requirement is not fulfilled this function does not participate in overload resolution. /// \note The caller has to ensure that the lifetime of the \c RawAllocator is at least as long as the lifetime /// of this \ref std_allocator object. - template ::value))> + template < + class RawAlloc, + // MSVC seems to ignore access rights in decltype SFINAE below + // use this to prevent this constructor being chosen instead of move/copy for types inheriting from it + FOONATHAN_REQUIRES((!std::is_base_of::value))> std_allocator(RawAlloc& alloc, FOONATHAN_SFINAE(alloc_reference(alloc))) FOONATHAN_NOEXCEPT - : alloc_reference(alloc) + : alloc_reference(alloc) { } @@ -138,13 +143,14 @@ namespace foonathan /// \requires The \c RawAllocator is stateless /// and the expression allocator_reference(alloc) is well-formed as above, /// otherwise this function does not participate in overload resolution. - template ::value))> + template < + class RawAlloc, + // MSVC seems to ignore access rights in decltype SFINAE below + // use this to prevent this constructor being chosen instead of move/copy for types inheriting from it + FOONATHAN_REQUIRES((!std::is_base_of::value))> std_allocator(const RawAlloc& alloc, FOONATHAN_SFINAE(alloc_reference(alloc))) FOONATHAN_NOEXCEPT - : alloc_reference(alloc) + : alloc_reference(alloc) { } @@ -163,13 +169,13 @@ namespace foonathan /// This is required by the \c Allcoator concept and simply takes the same \ref allocator_reference. template std_allocator(const std_allocator& alloc) FOONATHAN_NOEXCEPT - : alloc_reference(alloc.get_allocator()) + : alloc_reference(alloc.get_allocator()) { } template std_allocator(std_allocator& alloc) FOONATHAN_NOEXCEPT - : alloc_reference(alloc.get_allocator()) + : alloc_reference(alloc.get_allocator()) { } /// @} From 3d78d53da6fd940cf7123e9de4d4fe9118abf1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Mon, 30 Oct 2017 10:17:17 +0100 Subject: [PATCH 08/13] Fix double free error in binary_segregator Fixes #16. --- include/foonathan/memory/segregator.hpp | 22 ++++++++++++++-------- test/segregator.cpp | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/foonathan/memory/segregator.hpp b/include/foonathan/memory/segregator.hpp index 0c6adc58..452f3d1e 100644 --- a/include/foonathan/memory/segregator.hpp +++ b/include/foonathan/memory/segregator.hpp @@ -124,8 +124,8 @@ namespace foonathan /// \ingroup memory adapter template class binary_segregator - : FOONATHAN_EBO( - detail::ebo_storage<1, typename allocator_traits::allocator_type>) + : FOONATHAN_EBO( + detail::ebo_storage<1, typename allocator_traits::allocator_type>) { using segregatable_traits = allocator_traits; using fallback_traits = allocator_traits; @@ -152,7 +152,9 @@ namespace foonathan if (get_segregatable().use_allocate_node(size, alignment)) return segregatable_traits::allocate_node(get_segregatable_allocator(), size, alignment); - return fallback_traits::allocate_node(get_fallback_allocator(), size, alignment); + else + return fallback_traits::allocate_node(get_fallback_allocator(), size, + alignment); } void deallocate_node(void* ptr, std::size_t size, @@ -161,7 +163,9 @@ namespace foonathan if (get_segregatable().use_allocate_node(size, alignment)) segregatable_traits::deallocate_node(get_segregatable_allocator(), ptr, size, alignment); - fallback_traits::deallocate_node(get_fallback_allocator(), ptr, size, alignment); + else + fallback_traits::deallocate_node(get_fallback_allocator(), ptr, size, + alignment); } void* allocate_array(std::size_t count, std::size_t size, std::size_t alignment) @@ -169,8 +173,9 @@ namespace foonathan if (get_segregatable().use_allocate_array(count, size, alignment)) return segregatable_traits::allocate_array(get_segregatable_allocator(), count, size, alignment); - return fallback_traits::allocate_array(get_fallback_allocator(), count, size, - alignment); + else + return fallback_traits::allocate_array(get_fallback_allocator(), count, size, + alignment); } void deallocate_array(void* array, std::size_t count, std::size_t size, @@ -179,8 +184,9 @@ namespace foonathan if (get_segregatable().use_allocate_array(count, size, alignment)) segregatable_traits::deallocate_array(get_segregatable_allocator(), array, count, size, alignment); - fallback_traits::deallocate_array(get_fallback_allocator(), array, count, size, - alignment); + else + fallback_traits::deallocate_array(get_fallback_allocator(), array, count, size, + alignment); } /// @} diff --git a/test/segregator.cpp b/test/segregator.cpp index de752531..530590c6 100644 --- a/test/segregator.cpp +++ b/test/segregator.cpp @@ -36,36 +36,50 @@ TEST_CASE("binary_segregator", "[adapter]") segregator s(threshold(8u, test_allocator{})); REQUIRE(s.get_segregatable_allocator().no_allocated() == 0u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 0u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); auto ptr = s.allocate_node(1u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_node(ptr, 1u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 1u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); ptr = s.allocate_node(8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_node(ptr, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 2u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); ptr = s.allocate_node(8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_node(ptr, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 3u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 0u); ptr = s.allocate_node(9u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 0u); REQUIRE(s.get_fallback_allocator().no_allocated() == 1u); s.deallocate_node(ptr, 9u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 3u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 1u); ptr = s.allocate_array(1u, 8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 1u); REQUIRE(s.get_fallback_allocator().no_allocated() == 0u); s.deallocate_array(ptr, 1u, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 4u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 1u); ptr = s.allocate_array(2u, 8u, 1u); REQUIRE(s.get_segregatable_allocator().no_allocated() == 0u); REQUIRE(s.get_fallback_allocator().no_allocated() == 1u); s.deallocate_array(ptr, 2u, 8u, 1u); + REQUIRE(s.get_segregatable_allocator().no_deallocated() == 4u); + REQUIRE(s.get_fallback_allocator().no_deallocated() == 2u); } TEST_CASE("segregator", "[adapter]") From 545f69c60557743c9f4be759c2e3f7b1d6002e58 Mon Sep 17 00:00:00 2001 From: nicolastagliani Date: Mon, 18 Sep 2017 13:17:28 +0200 Subject: [PATCH 09/13] Bump version number to 0.6 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36ce7e30..5e9871ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ cmake_minimum_required(VERSION 3.1) project(FOONATHAN_MEMORY) set(FOONATHAN_MEMORY_VERSION_MAJOR 0 CACHE STRING "major version of memory" FORCE) -set(FOONATHAN_MEMORY_VERSION_MINOR 5 CACHE STRING "minor version of memory" FORCE) +set(FOONATHAN_MEMORY_VERSION_MINOR 6 CACHE STRING "minor version of memory" FORCE) set(FOONATHAN_MEMORY_VERSION "${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}" CACHE STRING "version of memory" FORCE) From 1c5b52306297bb0b1c4437ef73cc09c746150a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Mon, 30 Oct 2017 19:14:01 +0100 Subject: [PATCH 10/13] Add and bump version patch number --- CMakeLists.txt | 3 ++- src/CMakeLists.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e9871ec..7d281b11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,8 @@ project(FOONATHAN_MEMORY) set(FOONATHAN_MEMORY_VERSION_MAJOR 0 CACHE STRING "major version of memory" FORCE) set(FOONATHAN_MEMORY_VERSION_MINOR 6 CACHE STRING "minor version of memory" FORCE) -set(FOONATHAN_MEMORY_VERSION "${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}" +set(FOONATHAN_MEMORY_VERSION_PATCH 1 CACHE STRING "patch version of memory" FORCE) +set(FOONATHAN_MEMORY_VERSION "${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}.${FOONATHAN_MEMORY_VERSION_PATCH}" CACHE STRING "version of memory" FORCE) include(cmake/compatibility.cmake) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1778d243..4cd5ccf5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,7 +97,8 @@ target_include_directories(foonathan_memory PUBLIC $ Date: Mon, 30 Oct 2017 19:16:26 +0100 Subject: [PATCH 11/13] Fix misuse of constexpr macro --- include/foonathan/memory/error.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/foonathan/memory/error.hpp b/include/foonathan/memory/error.hpp index 4b881707..c13dd5bc 100644 --- a/include/foonathan/memory/error.hpp +++ b/include/foonathan/memory/error.hpp @@ -35,7 +35,7 @@ namespace foonathan const void* allocator; /// \effects Creates it by giving it the name of the allocator and a pointer. - FOONATHAN_CONSTEXPR allocator_info(const char* n, const void* alloc) FOONATHAN_NOEXCEPT + FOONATHAN_CONSTEXPR_FNC allocator_info(const char* n, const void* alloc) FOONATHAN_NOEXCEPT : name(n), allocator(alloc) { @@ -44,13 +44,13 @@ namespace foonathan /// @{ /// \effects Compares two \ref allocator_info objects, they are equal, if the \ref allocator is the same. /// \returns The result of the comparision. - friend FOONATHAN_CONSTEXPR bool operator==(const allocator_info& a, + friend FOONATHAN_CONSTEXPR_FNC bool operator==(const allocator_info& a, const allocator_info& b) FOONATHAN_NOEXCEPT { return a.allocator == b.allocator; } - friend FOONATHAN_CONSTEXPR bool operator!=(const allocator_info& a, + friend FOONATHAN_CONSTEXPR_FNC bool operator!=(const allocator_info& a, const allocator_info& b) FOONATHAN_NOEXCEPT { return a.allocator != b.allocator; From abe7c91413b4a22d017c49337b78e76005286a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Mon, 30 Oct 2017 20:45:27 +0100 Subject: [PATCH 12/13] Add missing header to CMake Fixes #17. --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4cd5ccf5..6fad558f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ set(detail_header ${header_path}/detail/assert.hpp ${header_path}/detail/container_node_sizes.hpp ${header_path}/detail/debug_helpers.hpp + ${header_path}/detail/ebo_storage.hpp ${header_path}/detail/free_list.hpp ${header_path}/detail/free_list_array.hpp ${header_path}/detail/lowlevel_allocator.hpp From d5136bfc824c31d6ef7dc2a62a201c1788fb8473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Tue, 31 Oct 2017 13:09:22 +0100 Subject: [PATCH 13/13] Update changelog --- CHANGELOG.MD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 4321c28e..5bb022bb 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,3 +1,12 @@ +# 0.6-1 + +* fix CMake configuration error +* fix double free error in `segregator` +* add `static_assert()` when default constructing a stateful `std_allocator` +* fix various compiler warnings + +--- + # 0.6 ## Tool