From 187fd3e71ecbd34976ceb353b1179ad94b20a4b0 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Thu, 27 Apr 2023 12:00:42 -0700 Subject: [PATCH] Implement initializer_list assignment --- .../boost/unordered/concurrent_flat_map.hpp | 6 ++ .../unordered/detail/foa/concurrent_table.hpp | 12 +++ test/cfoa/assign_tests.cpp | 79 +++++++++++++++++-- 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/include/boost/unordered/concurrent_flat_map.hpp b/include/boost/unordered/concurrent_flat_map.hpp index 98dc2bd5..12778f64 100644 --- a/include/boost/unordered/concurrent_flat_map.hpp +++ b/include/boost/unordered/concurrent_flat_map.hpp @@ -267,6 +267,12 @@ namespace boost { return *this; } + concurrent_flat_map& operator=(std::initializer_list ilist) + { + table_ = ilist; + return *this; + } + /// Capacity /// diff --git a/include/boost/unordered/detail/foa/concurrent_table.hpp b/include/boost/unordered/detail/foa/concurrent_table.hpp index d5e877cc..fe314034 100644 --- a/include/boost/unordered/detail/foa/concurrent_table.hpp +++ b/include/boost/unordered/detail/foa/concurrent_table.hpp @@ -410,6 +410,18 @@ public: return *this; } + concurrent_table& operator=(std::initializer_list il) { + auto lck=exclusive_access(); + super::clear(); + if (super::capacity()unprotected_emplace(v); + } + return *this; + } + allocator_type get_allocator()const noexcept { auto lck=shared_access(); diff --git a/test/cfoa/assign_tests.cpp b/test/cfoa/assign_tests.cpp index 8734433f..92ba0bbf 100644 --- a/test/cfoa/assign_tests.cpp +++ b/test/cfoa/assign_tests.cpp @@ -317,6 +317,26 @@ namespace { template void move_assign(G gen, test::random_generator rg) { + using pocma_allocator_type = pocma_allocator >; + + using pocma_map_type = boost::unordered::concurrent_flat_map; + + BOOST_STATIC_ASSERT( + std::is_nothrow_move_assignable, std::equal_to, + std::allocator > > >::value); + + BOOST_STATIC_ASSERT( + std::is_nothrow_move_assignable, std::equal_to, + pocma_allocator > > >::value); + + BOOST_STATIC_ASSERT( + !std::is_nothrow_move_assignable, std::equal_to, + stateful_allocator > > >::value); + auto values = make_random_values(1024 * 16, [&] { return gen(rg); }); auto reference_map = boost::unordered_flat_map(values.begin(), values.end()); @@ -583,12 +603,6 @@ namespace { { raii::reset_counts(); - using pocma_allocator_type = - pocma_allocator >; - - using pocma_map_type = boost::unordered::concurrent_flat_map; - pocma_map_type x(values.begin(), values.end(), values.size(), hasher(1), key_equal(2), pocma_allocator_type(3)); @@ -671,6 +685,59 @@ namespace { } check_raii_counts(); } + + UNORDERED_AUTO_TEST (initializer_list_assignment) { + std::initializer_list values{ + map_value_type{raii{0}, raii{0}}, + map_value_type{raii{1}, raii{1}}, + map_value_type{raii{2}, raii{2}}, + map_value_type{raii{3}, raii{3}}, + map_value_type{raii{4}, raii{4}}, + map_value_type{raii{5}, raii{5}}, + map_value_type{raii{6}, raii{6}}, + map_value_type{raii{6}, raii{6}}, + map_value_type{raii{7}, raii{7}}, + map_value_type{raii{8}, raii{8}}, + map_value_type{raii{9}, raii{9}}, + map_value_type{raii{10}, raii{10}}, + map_value_type{raii{9}, raii{9}}, + map_value_type{raii{8}, raii{8}}, + map_value_type{raii{7}, raii{7}}, + map_value_type{raii{6}, raii{6}}, + map_value_type{raii{5}, raii{5}}, + map_value_type{raii{4}, raii{4}}, + map_value_type{raii{3}, raii{3}}, + map_value_type{raii{2}, raii{2}}, + map_value_type{raii{1}, raii{1}}, + map_value_type{raii{0}, raii{0}}, + }; + + auto reference_map = + boost::unordered_flat_map(values.begin(), values.end()); + auto v = std::vector(values.begin(), values.end()); + + { + raii::reset_counts(); + map_type x(0, hasher(1), key_equal(2), allocator_type(3)); + + thread_runner(v, [&x, &values](boost::span s) { + (void)s; + x = values; + }); + + test_matches_reference(x, reference_map); + BOOST_TEST_EQ(x.hash_function(), hasher(1)); + BOOST_TEST_EQ(x.key_eq(), key_equal(2)); + BOOST_TEST(x.get_allocator() == allocator_type(3)); + + BOOST_TEST_EQ(raii::copy_constructor, num_threads * 2 * x.size()); + BOOST_TEST_EQ(raii::destructor, (num_threads - 1) * 2 * x.size()); + BOOST_TEST_EQ(raii::move_constructor, 0u); + BOOST_TEST_EQ(raii::copy_assignment, 0u); + BOOST_TEST_EQ(raii::move_assignment, 0u); + } + check_raii_counts(); + } } // namespace // clang-format off