diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 936fc809..7b513443 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -71,4 +71,4 @@ jobs: name: Windows_Meson_Testlog path: | builddir/meson-logs/testlog.txt - builddir/test/udm.exe + builddir/test/udm-test.exe diff --git a/CMakeLists.txt b/CMakeLists.txt index 78cbab84..243dad8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.12) project("unordered_dense" - VERSION 4.0.1 + VERSION 4.0.2 DESCRIPTION "A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion" HOMEPAGE_URL "https://github.com/martinus/unordered_dense") diff --git a/include/ankerl/unordered_dense.h b/include/ankerl/unordered_dense.h index b8cacea7..4fad154b 100644 --- a/include/ankerl/unordered_dense.h +++ b/include/ankerl/unordered_dense.h @@ -1,7 +1,7 @@ ///////////////////////// ankerl::unordered_dense::{map, set} ///////////////////////// // A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion. -// Version 4.0.1 +// Version 4.0.2 // https://github.com/martinus/unordered_dense // // Licensed under the MIT License . @@ -32,7 +32,7 @@ // see https://semver.org/spec/v2.0.0.html #define ANKERL_UNORDERED_DENSE_VERSION_MAJOR 4 // NOLINT(cppcoreguidelines-macro-usage) incompatible API changes #define ANKERL_UNORDERED_DENSE_VERSION_MINOR 0 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible functionality -#define ANKERL_UNORDERED_DENSE_VERSION_PATCH 1 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible bug fixes +#define ANKERL_UNORDERED_DENSE_VERSION_PATCH 2 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible bug fixes // API versioning with inline namespace, see https://www.foonathan.net/2018/11/inline-namespaces/ @@ -906,8 +906,8 @@ class table : public std::conditional_t, base_table_type_map, bas auto ba = bucket_alloc(m_values.get_allocator()); if (nullptr != m_buckets) { bucket_alloc_traits::deallocate(ba, m_buckets, bucket_count()); + m_buckets = nullptr; } - m_buckets = nullptr; m_num_buckets = 0; m_max_bucket_capacity = 0; } @@ -1221,7 +1221,14 @@ class table : public std::conditional_t, base_table_type_map, bas if (&other != this) { deallocate_buckets(); // deallocate before m_values is set (might have another allocator) m_values = std::move(other.m_values); - m_buckets = std::exchange(other.m_buckets, nullptr); + + // we can only reuse m_buckets over when both maps have the same allocator! + if (get_allocator() == other.get_allocator()) { + m_buckets = std::exchange(other.m_buckets, nullptr); + } else { + copy_buckets(other); + } + m_num_buckets = std::exchange(other.m_num_buckets, 0); m_max_bucket_capacity = std::exchange(other.m_max_bucket_capacity, 0); m_max_load_factor = std::exchange(other.m_max_load_factor, default_max_load_factor); diff --git a/meson.build b/meson.build index cfee9a03..548df9d4 100644 --- a/meson.build +++ b/meson.build @@ -18,7 +18,7 @@ # project('unordered_dense', 'cpp', - version: '4.0.1', + version: '4.0.2', license: 'MIT', default_options : [ 'cpp_std=c++17', diff --git a/test/app/stacktrace.cpp b/test/app/stacktrace.cpp index c3aac2ed..b4ce517a 100644 --- a/test/app/stacktrace.cpp +++ b/test/app/stacktrace.cpp @@ -20,7 +20,7 @@ void handle(int sig) { // print out all the frames to stderr fmt::print(stderr, "Error: signal {}. See stacktrace with\n", sig); - fmt::print(stderr, "addr2line -Cafpie ./test/udm"); + fmt::print(stderr, "addr2line -Cafpie ./test/udm-test"); for (size_t i = 0; i < static_cast(size); ++i) { fmt::print(stderr, " {}", ary[i]); } diff --git a/test/meson.build b/test/meson.build index ae0361cb..082787ec 100644 --- a/test/meson.build +++ b/test/meson.build @@ -60,6 +60,7 @@ test_sources = [ 'unit/namespace.cpp', 'unit/not_copyable.cpp', 'unit/not_moveable.cpp', + 'unit/pmr_move_with_allocators.cpp', 'unit/pmr.cpp', 'unit/rehash.cpp', 'unit/replace.cpp', @@ -141,7 +142,7 @@ endif #endif test_exe = executable( - 'udm', + 'udm-test', test_sources, include_directories: incdir, cpp_args: cpp_args, diff --git a/test/unit/namespace.cpp b/test/unit/namespace.cpp index ad67dc17..1bfaa4a7 100644 --- a/test/unit/namespace.cpp +++ b/test/unit/namespace.cpp @@ -2,7 +2,7 @@ #include -namespace versioned_namespace = ankerl::unordered_dense::v4_0_1; +namespace versioned_namespace = ankerl::unordered_dense::v4_0_2; static_assert(std::is_same_v, ankerl::unordered_dense::map>); static_assert(std::is_same_v, ankerl::unordered_dense::hash>); diff --git a/test/unit/pmr.cpp b/test/unit/pmr.cpp index cf3ced10..b7613894 100644 --- a/test/unit/pmr.cpp +++ b/test/unit/pmr.cpp @@ -195,9 +195,9 @@ TEST_CASE("pmr_move_different_mr") { show(mr1, "mr1"); show(mr2, "mr2"); - REQUIRE(mr1.num_allocs() == 2); + REQUIRE(mr1.num_allocs() == 3); REQUIRE(mr1.num_deallocs() == 1); - REQUIRE(mr1.num_is_equals() == 0); + REQUIRE(mr1.num_is_equals() == 1); REQUIRE(mr2.num_allocs() == 2); REQUIRE(mr2.num_deallocs() == 0); diff --git a/test/unit/pmr_move_with_allocators.cpp b/test/unit/pmr_move_with_allocators.cpp new file mode 100644 index 00000000..7de9f765 --- /dev/null +++ b/test/unit/pmr_move_with_allocators.cpp @@ -0,0 +1,34 @@ +#include + +#define ENABLE_LOG_LINE +#include +#include + +#if defined(ANKERL_UNORDERED_DENSE_PMR) +// windows' vector has different allocation behavior, macos has linker errors +# if __linux__ + +using int_str_map = ankerl::unordered_dense::pmr::map; + +// creates a map and moves it out +auto return_hello_world(ANKERL_UNORDERED_DENSE_PMR::memory_resource* resource) { + int_str_map map_default_resource(resource); + map_default_resource[0] = "Hello"; + map_default_resource[1] = "World"; + return map_default_resource; +} + +TEST_CASE("move_with_allocators") { + int_str_map map_default_resource(ANKERL_UNORDERED_DENSE_PMR::new_delete_resource()); + + ANKERL_UNORDERED_DENSE_PMR::synchronized_pool_resource pool; + + // segfaults if m_buckets is reused + { + map_default_resource = return_hello_world(&pool); + REQUIRE(map_default_resource.contains(0)); + } +} + +# endif +#endif \ No newline at end of file