mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-31 20:04:29 +02:00
Add free function swap()
This commit is contained in:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user