Add free function swap()

This commit is contained in:
Christian Mazakas
2023-05-11 10:17:02 -07:00
parent 9260bff8f8
commit c3879e238d
2 changed files with 48 additions and 24 deletions

View File

@@ -149,8 +149,7 @@ namespace boost {
detail::foa::concurrent_table<type_policy, Hash, Pred, Allocator> table_; detail::foa::concurrent_table<type_policy, Hash, Pred, Allocator> table_;
template <class K, class V, class H, class KE, class A> template <class K, class V, class H, class KE, class A>
bool friend operator==( bool friend operator==(concurrent_flat_map<K, V, H, KE, A> const& lhs,
concurrent_flat_map<K, V, H, KE, A> const& lhs,
concurrent_flat_map<K, V, H, KE, A> const& rhs); concurrent_flat_map<K, V, H, KE, A> const& rhs);
public: public:
@@ -747,9 +746,7 @@ namespace boost {
/// Hash Policy /// Hash Policy
/// ///
size_type bucket_count() const noexcept { size_type bucket_count() const noexcept { return table_.capacity(); }
return table_.capacity();
}
float load_factor() const noexcept { return table_.load_factor(); } float load_factor() const noexcept { return table_.load_factor(); }
float max_load_factor() const noexcept float max_load_factor() const noexcept
@@ -788,7 +785,16 @@ namespace boost {
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
template <class Key, class T, class Hash, class Pred, class Alloc>
void swap(concurrent_flat_map<Key, T, Hash, Pred, Alloc>& x,
concurrent_flat_map<Key, T, Hash, Pred, Alloc>& y)
noexcept(noexcept(x.swap(y)))
{
x.swap(y);
}
} // namespace unordered } // namespace unordered
} // namespace boost } // namespace boost
#undef BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE #undef BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE

View File

@@ -83,8 +83,22 @@ BOOST_STATIC_ASSERT(is_nothrow_member_swappable<pocs_map_type>::value);
BOOST_STATIC_ASSERT(!is_nothrow_member_swappable<map_type>::value); BOOST_STATIC_ASSERT(!is_nothrow_member_swappable<map_type>::value);
namespace { namespace {
template <class X, class G> struct
void swap_tests(X*, G gen, test::random_generator rg) {
template <class T> void operator()(T& x1, T& x2) const { x1.swap(x2); }
} member_fn_swap;
struct
{
template <class T> void operator()(T& x1, T& x2) const
{
using boost::unordered::swap;
swap(x1, x2);
}
} free_fn_swap;
template <class X, class F, class G>
void swap_tests(X*, F swapper, G gen, test::random_generator rg)
{ {
using allocator = typename X::allocator_type; using allocator = typename X::allocator_type;
@@ -118,11 +132,11 @@ namespace {
auto const old_cc = +raii::copy_constructor; auto const old_cc = +raii::copy_constructor;
auto const old_mc = +raii::move_constructor; auto const old_mc = +raii::move_constructor;
thread_runner(vals1, [&x1, &x2](boost::span<map_value_type> s) { thread_runner(vals1, [&x1, &x2, swapper](boost::span<map_value_type> s) {
(void)s; (void)s;
x1.swap(x2); swapper(x1, x2);
x2.swap(x1); swapper(x2, x1);
}); });
BOOST_TEST_EQ(raii::copy_constructor, old_cc); BOOST_TEST_EQ(raii::copy_constructor, old_cc);
@@ -163,7 +177,8 @@ namespace {
check_raii_counts(); check_raii_counts();
} }
template <class G> void insert_and_swap(G gen, test::random_generator rg) template <class F, class G>
void insert_and_swap(F swapper, G gen, test::random_generator rg)
{ {
auto vals1 = make_random_values(1024 * 8, [&] { return gen(rg); }); auto vals1 = make_random_values(1024 * 8, [&] { return gen(rg); });
auto vals2 = make_random_values(1024 * 4, [&] { return gen(rg); }); auto vals2 = make_random_values(1024 * 4, [&] { return gen(rg); });
@@ -208,13 +223,14 @@ namespace {
done2 = true; done2 = true;
}); });
t3 = std::thread([&x1, &x2, &m, &cv, &done1, &done2, &num_swaps] { t3 =
std::thread([&x1, &x2, &m, &cv, &done1, &done2, &num_swaps, swapper] {
do { do {
{ {
std::unique_lock<std::mutex> lk(m); std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [] { return true; }); cv.wait(lk, [] { return true; });
} }
x1.swap(x2); swapper(x1, x2);
++num_swaps; ++num_swaps;
std::this_thread::yield(); std::this_thread::yield();
} while (!done1 || !done2); } while (!done1 || !done2);
@@ -258,10 +274,12 @@ namespace {
UNORDERED_TEST( UNORDERED_TEST(
swap_tests, swap_tests,
((map)(pocs_map)) ((map)(pocs_map))
((member_fn_swap)(free_fn_swap))
((value_type_generator)) ((value_type_generator))
((default_generator)(sequential)(limited_range))) ((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(insert_and_swap, UNORDERED_TEST(insert_and_swap,
((member_fn_swap)(free_fn_swap))
((value_type_generator)) ((value_type_generator))
((default_generator)(sequential)(limited_range))) ((default_generator)(sequential)(limited_range)))
// clang-format on // clang-format on