Sync from upstream.

This commit is contained in:
Rene Rivera
2024-08-26 07:13:46 -05:00
60 changed files with 7012 additions and 339 deletions
+1 -1
View File
@@ -135,7 +135,7 @@ foa_tests(SOURCES exception/merge_exception_tests.cpp)
# CFOA tests
cfoa_tests(SOURCES cfoa/insert_tests.cpp)
cfoa_tests(SOURCES cfoa/insert_tests.cpp COMPILE_OPTIONS $<$<CXX_COMPILER_ID:MSVC>:/bigobj>)
cfoa_tests(SOURCES cfoa/erase_tests.cpp)
cfoa_tests(SOURCES cfoa/try_emplace_tests.cpp)
cfoa_tests(SOURCES cfoa/emplace_tests.cpp)
+28 -2
View File
@@ -113,6 +113,7 @@ local FCA_TESTS =
move_tests
narrow_cast_tests
node_handle_tests
node_handle_allocator_tests
noexcept_tests
post_move_tests
prime_fmod_tests
@@ -235,6 +236,7 @@ local FOA_TESTS =
fancy_pointer_noleak
pmr_allocator_tests
stats_tests
node_handle_allocator_tests
;
for local test in $(FOA_TESTS)
@@ -316,11 +318,10 @@ alias foa_tests :
;
local CFOA_TESTS =
insert_tests
erase_tests
try_emplace_tests
emplace_tests
visit_tests
extract_insert_tests
constructor_tests
assign_tests
clear_tests
@@ -346,6 +347,7 @@ local CFOA_TESTS =
explicit_alloc_ctor_tests
pmr_allocator_tests
stats_tests
node_handle_allocator_tests
;
for local test in $(CFOA_TESTS)
@@ -356,6 +358,28 @@ for local test in $(CFOA_TESTS)
;
}
run cfoa/insert_tests.cpp
:
:
: $(CPP11) <threading>multi
<toolset>msvc:<cxxflags>/bigobj
<toolset>gcc:<inlining>on
<toolset>gcc:<optimization>space
<toolset>clang:<inlining>on
<toolset>clang:<optimization>space
: cfoa_insert_tests ;
run cfoa/visit_tests.cpp
:
:
: $(CPP11) <threading>multi
<toolset>msvc:<cxxflags>/bigobj
<toolset>gcc:<inlining>on
<toolset>gcc:<optimization>space
<toolset>clang:<inlining>on
<toolset>clang:<optimization>space
: cfoa_visit_tests ;
run cfoa/serialization_tests.cpp
:
:
@@ -395,6 +419,8 @@ make_cfoa_interprocess_concurrency_tests cfoa_interproc_conc_tests_stats
alias cfoa_tests :
cfoa_$(CFOA_TESTS)
cfoa_insert_tests
cfoa_visit_tests
cfoa_serialization_tests
cfoa_interproc_conc_tests
cfoa_interproc_conc_tests_stats ;
+54 -28
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#if defined(__clang__) && defined(__has_warning)
@@ -37,19 +39,35 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using fancy_map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator2<std::pair<raii const, raii> > >;
using fancy_node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator2<std::pair<raii const, raii> > >;
using fancy_set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator2<raii> >;
using fancy_node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator2<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
fancy_map_type* fancy_test_map;
fancy_node_map_type* fancy_test_node_map;
fancy_set_type* fancy_test_set;
fancy_node_set_type* fancy_test_node_set;
std::initializer_list<map_type::value_type> map_init_list{
{raii{0}, raii{0}},
@@ -102,7 +120,9 @@ std::initializer_list<set_type::value_type> set_init_list{
};
auto test_map_and_init_list=std::make_pair(test_map,map_init_list);
auto test_node_map_and_init_list=std::make_pair(test_node_map,map_init_list);
auto test_set_and_init_list=std::make_pair(test_set,set_init_list);
auto test_node_set_and_init_list=std::make_pair(test_node_set,set_init_list);
template <class T,bool POCCA, bool POCMA>
struct poca_allocator: fancy_allocator<T>
@@ -928,7 +948,7 @@ namespace {
}
template <class X, class GF>
void flat_move_assign(X*, GF gen_factory, test::random_generator rg)
void nonconcurrent_move_assign(X*, GF gen_factory, test::random_generator rg)
{
using value_type = typename X::value_type;
static constexpr auto value_type_cardinality =
@@ -950,16 +970,17 @@ namespace {
{
raii::reset_counts();
flat_container<X> flat(values.begin(), values.end(), values.size(),
nonconcurrent_container<X> nonc(
values.begin(), values.end(), values.size(),
hasher(1), key_equal(2), allocator_type(3));
X x(0, hasher(2), key_equal(1), allocator_type(3));
BOOST_TEST(flat.get_allocator() == x.get_allocator());
BOOST_TEST(nonc.get_allocator() == x.get_allocator());
x = std::move(flat);
x = std::move(nonc);
BOOST_TEST(flat.empty());
BOOST_TEST(nonc.empty());
BOOST_TEST_EQ(x.size(), reference_cont.size());
test_fuzzy_matches_reference(x, reference_cont, rg);
@@ -983,17 +1004,18 @@ namespace {
X x(values.begin(), values.end(), values.size(), hasher(1),
key_equal(2), allocator_type(3));
flat_container<X> flat(0, hasher(2), key_equal(1), allocator_type(3));
nonconcurrent_container<X> nonc(
0, hasher(2), key_equal(1), allocator_type(3));
BOOST_TEST(flat.get_allocator() == x.get_allocator());
BOOST_TEST(nonc.get_allocator() == x.get_allocator());
flat = std::move(x);
nonc = std::move(x);
BOOST_TEST(x.empty());
BOOST_TEST_EQ(flat.size(), reference_cont.size());
BOOST_TEST_EQ(nonc.size(), reference_cont.size());
BOOST_TEST_EQ(flat.hash_function(), hasher(1));
BOOST_TEST_EQ(flat.key_eq(), key_equal(2));
BOOST_TEST_EQ(nonc.hash_function(), hasher(1));
BOOST_TEST_EQ(nonc.key_eq(), key_equal(2));
BOOST_TEST_EQ(
raii::copy_constructor, value_type_cardinality * reference_cont.size());
@@ -1008,16 +1030,17 @@ namespace {
{
raii::reset_counts();
flat_container<X> flat(values.begin(), values.end(), values.size(),
nonconcurrent_container<X> nonc(
values.begin(), values.end(), values.size(),
hasher(1), key_equal(2), allocator_type(3));
X x(0, hasher(2), key_equal(1), allocator_type(4));
BOOST_TEST(flat.get_allocator() != x.get_allocator());
BOOST_TEST(nonc.get_allocator() != x.get_allocator());
x = std::move(flat);
x = std::move(nonc);
BOOST_TEST(flat.empty());
BOOST_TEST(nonc.empty());
BOOST_TEST_EQ(x.size(), reference_cont.size());
test_fuzzy_matches_reference(x, reference_cont, rg);
@@ -1043,17 +1066,18 @@ namespace {
X x(values.begin(), values.end(), values.size(), hasher(1),
key_equal(2), allocator_type(3));
flat_container<X> flat(0, hasher(2), key_equal(1), allocator_type(4));
nonconcurrent_container<X> nonc(
0, hasher(2), key_equal(1), allocator_type(4));
BOOST_TEST(flat.get_allocator() != x.get_allocator());
BOOST_TEST(nonc.get_allocator() != x.get_allocator());
flat = std::move(x);
nonc = std::move(x);
BOOST_TEST(x.empty());
BOOST_TEST_EQ(flat.size(), reference_cont.size());
BOOST_TEST_EQ(nonc.size(), reference_cont.size());
BOOST_TEST_EQ(flat.hash_function(), hasher(1));
BOOST_TEST_EQ(flat.key_eq(), key_equal(2));
BOOST_TEST_EQ(nonc.hash_function(), hasher(1));
BOOST_TEST_EQ(nonc.key_eq(), key_equal(2));
BOOST_TEST_EQ(
raii::copy_constructor, value_type_cardinality * reference_cont.size());
@@ -1073,29 +1097,31 @@ namespace {
// clang-format off
UNORDERED_TEST(
copy_assign,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
move_assign,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
initializer_list_assign,
((test_map_and_init_list)(test_set_and_init_list)))
((test_map_and_init_list)(test_node_map_and_init_list)
(test_set_and_init_list)(test_node_set_and_init_list)))
UNORDERED_TEST(
insert_and_assign,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((init_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
flat_move_assign,
((test_map)(test_set)(fancy_test_map)(fancy_test_set))
nonconcurrent_move_assign,
((test_map)(test_node_map)(test_set)(test_node_set)
(fancy_test_map)(fancy_test_node_map)(fancy_test_set)(fancy_test_node_set))
((init_type_generator_factory))
((default_generator)(sequential)(limited_range)))
// clang-format on
+13 -3
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
test::seed_t initialize_seed{674140082};
@@ -20,11 +22,19 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
namespace {
template <class X, class GF>
@@ -130,12 +140,12 @@ namespace {
// clang-format off
UNORDERED_TEST(
clear_tests,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(insert_and_clear,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
// clang-format on
+88 -8
View File
@@ -1,15 +1,19 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNORDERED_TEST_CFOA_COMMON_HELPERS_HPP
#define BOOST_UNORDERED_TEST_CFOA_COMMON_HELPERS_HPP
#include <boost/unordered/concurrent_flat_map_fwd.hpp>
#include <boost/unordered/concurrent_flat_set_fwd.hpp>
#include <boost/unordered/concurrent_node_map_fwd.hpp>
#include <boost/unordered/concurrent_node_set_fwd.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
#include <boost/unordered/unordered_flat_set.hpp>
#include <boost/unordered/unordered_node_map.hpp>
#include <boost/unordered/unordered_node_set.hpp>
#include <cstddef>
#include <type_traits>
@@ -27,6 +31,31 @@ struct value_cardinality<std::pair<K, V> >
static constexpr std::size_t value=2;
};
template <typename K>
struct value_nonconst_cardinality
{
static constexpr std::size_t value=1;
};
template <typename K, typename V>
struct value_nonconst_cardinality<std::pair<K, V> >
{
static constexpr std::size_t value=
1 * !std::is_const<K>::value +
1 * !std::is_const<V>::value ;
};
template <class Container>
struct is_container_node_based: std::false_type {};
template <typename K, typename V, typename H, typename P, typename A>
struct is_container_node_based<boost::concurrent_node_map<K, V, H, P, A> >
: std::true_type {};
template <typename K, typename H, typename P, typename A>
struct is_container_node_based<boost::concurrent_node_set<K, H, P, A> >
: std::true_type {};
template <class Container>
struct reference_container_impl;
@@ -39,30 +68,55 @@ struct reference_container_impl<boost::concurrent_flat_map<K, V, H, P, A> >
using type = boost::unordered_flat_map<K, V>;
};
template <typename K, typename V, typename H, typename P, typename A>
struct reference_container_impl<boost::concurrent_node_map<K, V, H, P, A> >
{
using type = boost::unordered_node_map<K, V>;
};
template <typename K, typename H, typename P, typename A>
struct reference_container_impl<boost::concurrent_flat_set<K, H, P, A> >
{
using type = boost::unordered_flat_set<K>;
};
template <class Container>
struct flat_container_impl;
template <typename K, typename H, typename P, typename A>
struct reference_container_impl<boost::concurrent_node_set<K, H, P, A> >
{
using type = boost::unordered_node_set<K>;
};
template <class Container>
using flat_container = typename flat_container_impl<Container>::type;
struct nonconcurrent_container_impl;
template <class Container>
using nonconcurrent_container =
typename nonconcurrent_container_impl<Container>::type;
template <typename K, typename V, typename H, typename P, typename A>
struct flat_container_impl<boost::concurrent_flat_map<K, V, H, P, A> >
struct nonconcurrent_container_impl<boost::concurrent_flat_map<K, V, H, P, A> >
{
using type = boost::unordered_flat_map<K, V, H, P, A>;
};
template <typename K, typename V, typename H, typename P, typename A>
struct nonconcurrent_container_impl<boost::concurrent_node_map<K, V, H, P, A> >
{
using type = boost::unordered_node_map<K, V, H, P, A>;
};
template <typename K, typename H, typename P, typename A>
struct flat_container_impl<boost::concurrent_flat_set<K, H, P, A> >
struct nonconcurrent_container_impl<boost::concurrent_flat_set<K, H, P, A> >
{
using type = boost::unordered_flat_set<K, H, P, A>;
};
template <typename K, typename H, typename P, typename A>
struct nonconcurrent_container_impl<boost::concurrent_node_set<K, H, P, A> >
{
using type = boost::unordered_node_set<K, H, P, A>;
};
template <typename Container, template <typename> class Allocator>
struct replace_allocator_impl;
@@ -95,7 +149,33 @@ struct replace_allocator_impl<
using type =
boost::concurrent_flat_set<K, H, P, Allocator<value_type> >;
};
template <
typename K, typename V, typename H, typename P, typename A,
template <typename> class Allocator
>
struct replace_allocator_impl<
boost::concurrent_node_map<K, V, H, P, A>, Allocator>
{
using value_type =
typename boost::concurrent_node_map<K, V, H, P, A>::value_type;
using type =
boost::concurrent_node_map<K, V, H, P, Allocator<value_type> >;
};
template <
typename K, typename H, typename P, typename A,
template <typename> class Allocator
>
struct replace_allocator_impl<
boost::concurrent_node_set<K, H, P, A>, Allocator>
{
using value_type =
typename boost::concurrent_node_set<K, H, P, A>::value_type;
using type =
boost::concurrent_node_set<K, H, P, Allocator<value_type> >;
};
template <typename K>
K const& get_key(K const& x) { return x; }
+52 -37
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
test::seed_t initialize_seed(4122023);
@@ -52,11 +54,19 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
std::initializer_list<map_type::value_type> map_init_list{
{raii{0}, raii{0}},
@@ -109,7 +119,9 @@ std::initializer_list<set_type::value_type> set_init_list{
};
auto test_map_and_init_list=std::make_pair(test_map,map_init_list);
auto test_node_map_and_init_list=std::make_pair(test_node_map,map_init_list);
auto test_set_and_init_list=std::make_pair(test_set,set_init_list);
auto test_node_set_and_init_list=std::make_pair(test_node_set,set_init_list);
namespace {
template <class X>
@@ -865,7 +877,7 @@ namespace {
}
template <class X, class GF>
void flat_constructor(X*, GF gen_factory, test::random_generator rg)
void nonconcurrent_constructor(X*, GF gen_factory, test::random_generator rg)
{
using value_type = typename X::value_type;
static constexpr auto value_type_cardinality =
@@ -875,12 +887,13 @@ namespace {
auto gen = gen_factory.template get<X>();
auto values = make_random_values(1024 * 16, [&] { return gen(rg); });
auto reference_cont = reference_container<X>(values.begin(), values.end());
auto reference_flat= flat_container<X>(values.begin(), values.end());
auto reference_nonc =
nonconcurrent_container<X>(values.begin(), values.end());
raii::reset_counts();
{
flat_container<X> flat(
nonconcurrent_container<X> nonc(
values.begin(), values.end(), reference_cont.size(), hasher(1),
key_equal(2), allocator_type(3));
@@ -890,9 +903,9 @@ namespace {
BOOST_TEST_EQ(old_dc, 0u);
BOOST_TEST_EQ(old_mc, 0u);
BOOST_TEST_EQ(old_cc, value_type_cardinality * flat.size());
BOOST_TEST_EQ(old_cc, value_type_cardinality * nonc.size());
X x(std::move(flat));
X x(std::move(nonc));
test_fuzzy_matches_reference(x, reference_cont, rg);
@@ -904,15 +917,16 @@ namespace {
BOOST_TEST_EQ(x.key_eq(), key_equal(2));
BOOST_TEST(x.get_allocator() == allocator_type(3));
BOOST_TEST(flat.empty());
BOOST_TEST(nonc.empty());
}
check_raii_counts();
{
flat_container<X> flat(0, hasher(1), key_equal(2), allocator_type(3));
nonconcurrent_container<X> nonc(
0, hasher(1), key_equal(2), allocator_type(3));
X x(std::move(flat));
X x(std::move(nonc));
BOOST_TEST(x.empty());
@@ -920,7 +934,7 @@ namespace {
BOOST_TEST_EQ(x.key_eq(), key_equal(2));
BOOST_TEST(x.get_allocator() == allocator_type(3));
BOOST_TEST(flat.empty());
BOOST_TEST(nonc.empty());
}
check_raii_counts();
@@ -937,17 +951,17 @@ namespace {
BOOST_TEST_EQ(old_mc, 0u);
BOOST_TEST_EQ(old_cc, 2u * value_type_cardinality * x.size());
flat_container<X> flat(std::move(x));
nonconcurrent_container<X> nonc(std::move(x));
BOOST_TEST(flat == reference_flat);
BOOST_TEST(nonc == reference_nonc);
BOOST_TEST_EQ(+raii::default_constructor, old_dc);
BOOST_TEST_EQ(+raii::move_constructor, old_mc);
BOOST_TEST_EQ(+raii::copy_constructor, old_cc);
BOOST_TEST_EQ(flat.hash_function(), hasher(1));
BOOST_TEST_EQ(flat.key_eq(), key_equal(2));
BOOST_TEST(flat.get_allocator() == allocator_type(3));
BOOST_TEST_EQ(nonc.hash_function(), hasher(1));
BOOST_TEST_EQ(nonc.key_eq(), key_equal(2));
BOOST_TEST(nonc.get_allocator() == allocator_type(3));
BOOST_TEST(x.empty());
}
@@ -957,13 +971,13 @@ namespace {
{
X x(0, hasher(1), key_equal(2), allocator_type(3));
flat_container<X> flat(std::move(x));
nonconcurrent_container<X> nonc(std::move(x));
BOOST_TEST(flat.empty());
BOOST_TEST(nonc.empty());
BOOST_TEST_EQ(flat.hash_function(), hasher(1));
BOOST_TEST_EQ(flat.key_eq(), key_equal(2));
BOOST_TEST(flat.get_allocator() == allocator_type(3));
BOOST_TEST_EQ(nonc.hash_function(), hasher(1));
BOOST_TEST_EQ(nonc.key_eq(), key_equal(2));
BOOST_TEST(nonc.get_allocator() == allocator_type(3));
BOOST_TEST(x.empty());
}
@@ -976,83 +990,84 @@ namespace {
// clang-format off
UNORDERED_TEST(
default_constructor,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
bucket_count_with_hasher_key_equal_and_allocator,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
soccc,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
from_iterator_range,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
copy_constructor,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
copy_constructor_with_insertion,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
move_constructor,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
move_constructor_with_insertion,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
iterator_range_with_allocator,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
explicit_allocator,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
initializer_list_with_all_params,
((test_map_and_init_list)(test_set_and_init_list)))
((test_map_and_init_list)(test_node_map_and_init_list)
(test_set_and_init_list)(test_node_set_and_init_list)))
UNORDERED_TEST(
bucket_count_and_allocator,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
bucket_count_with_hasher_and_allocator,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
iterator_range_with_bucket_count_and_allocator,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
iterator_range_with_bucket_count_hasher_and_allocator,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
flat_constructor,
((test_map)(test_set))
nonconcurrent_constructor,
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
// clang-format on
+27 -11
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Copyright (C) 2024 Braden Ganetsky
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +9,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -80,11 +82,8 @@ namespace {
}
template <class T, class X> void operator()(std::vector<T>& values, X& x)
{
static constexpr auto value_type_cardinality =
value_cardinality<typename X::value_type>::value;
call_impl(values, x);
BOOST_TEST_GE(raii::move_constructor, value_type_cardinality * x.size());
BOOST_TEST_GE(raii::move_constructor, x.size());
}
} lvalue_emplacer;
@@ -197,7 +196,12 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, value_type_cardinality * x.size());
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else {
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::copy_assignment, 0u);
BOOST_TEST_EQ(raii::move_assignment, 0u);
@@ -208,8 +212,8 @@ namespace {
{
template <class T, class X> void operator()(std::vector<T>& values, X& x)
{
static constexpr auto value_type_cardinality =
value_cardinality<typename X::value_type>::value;
static constexpr auto input_type_nonconst_cardinality =
value_nonconst_cardinality<T>::value;
std::atomic<std::uint64_t> num_inserts{0};
thread_runner(values, [&x, &num_inserts](boost::span<T> s) {
@@ -235,10 +239,18 @@ namespace {
} else {
BOOST_TEST_EQ(raii::copy_constructor, 0u);
}
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(
raii::move_constructor, input_type_nonconst_cardinality * x.size());
}
else {
BOOST_TEST_GT(
raii::move_constructor, input_type_nonconst_cardinality * x.size());
}
#if defined(BOOST_MSVC)
#pragma warning(pop) // C4127
#endif
BOOST_TEST_GT(raii::move_constructor, value_type_cardinality * x.size());
BOOST_TEST_EQ(raii::copy_assignment, 0u);
BOOST_TEST_EQ(raii::move_assignment, 0u);
@@ -280,7 +292,9 @@ namespace {
}
boost::unordered::concurrent_flat_map<raii, raii>* map;
boost::unordered::concurrent_node_map<raii, raii>* node_map;
boost::unordered::concurrent_flat_set<raii>* set;
boost::unordered::concurrent_node_set<raii>* node_set;
} // namespace
@@ -292,7 +306,7 @@ using test::sequential;
UNORDERED_TEST(
emplace,
((map)(set))
((map)(node_map)(set)(node_set))
((value_type_generator_factory)(init_type_generator_factory))
((lvalue_emplacer)(norehash_lvalue_emplacer)
(lvalue_emplace_or_cvisit)(lvalue_emplace_or_visit)(copy_emplacer)(move_emplacer))
@@ -455,6 +469,8 @@ namespace {
boost::unordered::concurrent_flat_map<counted_key_type, counted_value_type>*
test_counted_flat_map = {};
boost::unordered::concurrent_node_map<counted_key_type, counted_value_type>*
test_counted_node_map = {};
} // namespace
@@ -462,7 +478,7 @@ namespace {
UNORDERED_TEST(
emplace_map_key_value,
((test_counted_flat_map))
((test_counted_flat_map)(test_counted_node_map))
((copy)(move))
((counted_key_checker)(converting_key_checker))
((counted_value_checker)(converting_value_checker))
+35 -13
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
test::seed_t initialize_seed{1634048962};
@@ -20,28 +22,38 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
namespace {
UNORDERED_AUTO_TEST (simple_map_equality) {
using allocator_type = map_type::allocator_type;
template <class X>
void simple_map_equality(X*)
{
using allocator_type = typename X::allocator_type;
{
map_type x1(
X x1(
{{1, 11}, {2, 22}}, 0, hasher(1), key_equal(2), allocator_type(3));
map_type x2(
X x2(
{{1, 11}, {2, 22}}, 0, hasher(2), key_equal(2), allocator_type(3));
map_type x3(
X x3(
{{1, 11}, {2, 23}}, 0, hasher(2), key_equal(2), allocator_type(3));
map_type x4({{1, 11}}, 0, hasher(2), key_equal(2), allocator_type(3));
X x4({{1, 11}}, 0, hasher(2), key_equal(2), allocator_type(3));
BOOST_TEST_EQ(x1.size(), x2.size());
BOOST_TEST(x1 == x2);
@@ -57,17 +69,19 @@ namespace {
}
}
UNORDERED_AUTO_TEST (simple_set_equality) {
using allocator_type = set_type::allocator_type;
template <class X>
void simple_set_equality(X*)
{
using allocator_type = typename X::allocator_type;
{
set_type x1(
X x1(
{1, 2}, 0, hasher(1), key_equal(2), allocator_type(3));
set_type x2(
X x2(
{1, 2}, 0, hasher(2), key_equal(2), allocator_type(3));
set_type x3({1}, 0, hasher(2), key_equal(2), allocator_type(3));
X x3({1}, 0, hasher(2), key_equal(2), allocator_type(3));
BOOST_TEST_EQ(x1.size(), x2.size());
BOOST_TEST(x1 == x2);
@@ -165,9 +179,17 @@ namespace {
} // namespace
// clang-format off
UNORDERED_TEST(
simple_map_equality,
((test_map)(test_node_map)))
UNORDERED_TEST(
simple_set_equality,
((test_set)(test_node_set)))
UNORDERED_TEST(
insert_and_compare,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
// clang-format on
+11 -3
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -439,11 +441,17 @@ namespace {
}
boost::unordered::concurrent_flat_map<raii, raii>* map;
boost::unordered::concurrent_node_map<raii, raii>* node_map;
boost::unordered::concurrent_flat_set<raii>* set;
boost::unordered::concurrent_node_set<raii>* node_set;
boost::unordered::concurrent_flat_map<raii, raii, transp_hash,
transp_key_equal>* transparent_map;
boost::unordered::concurrent_node_map<raii, raii, transp_hash,
transp_key_equal>* transparent_node_map;
boost::unordered::concurrent_flat_set<raii, transp_hash,
transp_key_equal>* transparent_set;
boost::unordered::concurrent_node_set<raii, transp_hash,
transp_key_equal>* transparent_node_set;
} // namespace
@@ -454,14 +462,14 @@ using test::sequential;
// clang-format off
UNORDERED_TEST(
erase,
((map)(set))
((map)(node_map)(set)(node_set))
((value_type_generator_factory)(init_type_generator_factory))
((lvalue_eraser)(lvalue_eraser_if)(erase_if)(free_fn_erase_if)(erase_if_exec_policy))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
erase,
((transparent_map)(transparent_set))
((transparent_map)(transparent_node_map)(transparent_set)(transparent_node_set))
((value_type_generator_factory)(init_type_generator_factory))
((transp_lvalue_eraser)(transp_lvalue_eraser_if)(erase_if_exec_policy))
((default_generator)(sequential)(limited_range)))
+17 -4
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
using hasher = stateful_hash;
using key_equal = stateful_key_equal;
@@ -14,11 +16,19 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
std::initializer_list<map_type::value_type> map_init_list{
{raii{0}, raii{0}},
@@ -71,7 +81,9 @@ std::initializer_list<set_type::value_type> set_init_list{
};
auto test_map_and_init_list=std::make_pair(test_map,map_init_list);
auto test_node_map_and_init_list=std::make_pair(test_node_map,map_init_list);
auto test_set_and_init_list=std::make_pair(test_set,set_init_list);
auto test_node_set_and_init_list=std::make_pair(test_node_set,set_init_list);
namespace {
test::seed_t initialize_seed(1794114520);
@@ -206,19 +218,20 @@ using test::sequential;
// clang-format off
UNORDERED_TEST(
copy_assign,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((exception_value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
move_assign,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((exception_value_type_generator_factory))
((default_generator)(sequential)))
UNORDERED_TEST(
intializer_list_assign,
((test_map_and_init_list)(test_set_and_init_list)))
((test_map_and_init_list)(test_node_map_and_init_list)
(test_set_and_init_list)(test_node_set_and_init_list)))
// clang-format on
RUN_TESTS()
+19 -6
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
using hasher = stateful_hash;
using key_equal = stateful_key_equal;
@@ -14,11 +16,19 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
std::initializer_list<map_type::value_type> map_init_list{
{raii{0}, raii{0}},
@@ -71,7 +81,9 @@ std::initializer_list<set_type::value_type> set_init_list{
};
auto test_map_and_init_list=std::make_pair(test_map,map_init_list);
auto test_node_map_and_init_list=std::make_pair(test_node_map,map_init_list);
auto test_set_and_init_list=std::make_pair(test_set,set_init_list);
auto test_node_set_and_init_list=std::make_pair(test_node_set,set_init_list);
namespace {
test::seed_t initialize_seed(795610904);
@@ -339,29 +351,30 @@ using test::sequential;
// clang-format off
UNORDERED_TEST(
bucket_constructor,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
iterator_range,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((exception_value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
copy_constructor,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((exception_value_type_generator_factory))
((default_generator)(sequential)))
UNORDERED_TEST(
move_constructor,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((exception_value_type_generator_factory))
((default_generator)(sequential)))
UNORDERED_TEST(
initializer_list_bucket_count,
((test_map_and_init_list)(test_set_and_init_list)))
((test_map_and_init_list)(test_node_map_and_init_list)
(test_set_and_init_list)(test_node_set_and_init_list)))
// clang-format on
RUN_TESTS()
+8 -2
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -283,8 +285,12 @@ namespace {
boost::unordered::concurrent_flat_map<raii, raii, stateful_hash,
stateful_key_equal, stateful_allocator<std::pair<raii const, raii> > >* map;
boost::unordered::concurrent_node_map<raii, raii, stateful_hash,
stateful_key_equal, stateful_allocator<std::pair<raii const, raii> > >* node_map;
boost::unordered::concurrent_flat_set<raii, stateful_hash,
stateful_key_equal, stateful_allocator<raii> >* set;
boost::unordered::concurrent_node_set<raii, stateful_hash,
stateful_key_equal, stateful_allocator<raii> >* node_set;
} // namespace
@@ -295,7 +301,7 @@ using test::sequential;
// clang-format off
UNORDERED_TEST(
erase,
((map)(set))
((map)(node_map)(set)(node_set))
((exception_value_type_generator_factory)
(exception_init_type_generator_factory))
((lvalue_eraser)(lvalue_eraser_if)(erase_if)(free_fn_erase_if))
+36 -9
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -153,7 +155,15 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_GT(raii::copy_constructor, 0u);
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
} lvalue_insert_or_assign_copy_assign;
@@ -198,7 +208,7 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_GT(raii::copy_constructor, 0u);
BOOST_TEST_GT(raii::move_constructor, x.size()); // rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
} rvalue_insert_or_assign_copy_assign;
@@ -249,8 +259,15 @@ namespace {
BOOST_TEST_GT(num_inserts, 0u);
BOOST_TEST_EQ(raii::default_constructor, 0u);
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
} lvalue_insert_or_cvisit;
@@ -288,8 +305,14 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
} lvalue_insert_or_visit;
@@ -426,8 +449,12 @@ namespace {
boost::unordered::concurrent_flat_map<raii, raii, stateful_hash,
stateful_key_equal, stateful_allocator<std::pair<raii const, raii> > >* map;
boost::unordered::concurrent_node_map<raii, raii, stateful_hash,
stateful_key_equal, stateful_allocator<std::pair<raii const, raii> > >* node_map;
boost::unordered::concurrent_flat_set<raii, stateful_hash,
stateful_key_equal, stateful_allocator<raii> >* set;
boost::unordered::concurrent_node_set<raii, stateful_hash,
stateful_key_equal, stateful_allocator<raii> >* node_set;
} // namespace
@@ -438,7 +465,7 @@ using test::sequential;
// clang-format off
UNORDERED_TEST(
insert,
((map)(set))
((map)(node_map)(set)(node_set))
((exception_value_type_generator_factory)
(exception_init_type_generator_factory))
((lvalue_inserter)(rvalue_inserter)(iterator_range_inserter)
@@ -450,7 +477,7 @@ UNORDERED_TEST(
UNORDERED_TEST(
insert,
((map))
((map)(node_map))
((exception_init_type_generator_factory))
((lvalue_insert_or_assign_copy_assign)(lvalue_insert_or_assign_move_assign)
(rvalue_insert_or_assign_copy_assign)(rvalue_insert_or_assign_move_assign))
+12 -2
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -16,11 +18,19 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
namespace {
test::seed_t initialize_seed(223333016);
@@ -79,7 +89,7 @@ using test::sequential;
// clang-format off
UNORDERED_TEST(
merge,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((exception_value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
+2 -2
View File
@@ -1,6 +1,6 @@
// Copyright 2024 Joaquin M Lopez Muoz.
// Copyright 2024 Joaquin M Lopez Munoz.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at htT://www.boost.org/LICENSE_1_0.txt)
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_UNORDERED_CFOA_TESTS
#include "../unordered/explicit_alloc_ctor_tests.cpp"
+162
View File
@@ -0,0 +1,162 @@
// Copyright (C) 2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "helpers.hpp"
#include <boost/assert.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
using hasher = stateful_hash;
using key_equal = stateful_key_equal;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
node_map_type* test_node_map;
node_set_type* test_node_set;
namespace {
template <class X, class GF>
void extract_insert_tests(X*, GF gen_factory)
{
using value_type = typename X::value_type;
using allocator_type = typename X::allocator_type;
// set visit is always const access
using arg_visit_type = typename std::conditional<
std::is_same<typename X::key_type, typename X::value_type>::value,
typename X::value_type const,
typename X::value_type
>::type;
test::random_generator rg = test::sequential;
auto gen = gen_factory.template get<X>();
auto values = make_random_values(1024 * 16, [&] { return gen(rg); });
X in(0,hasher(1),key_equal(2), allocator_type(3));
std::vector<X> out(2,in);
for(std::size_t i = 0; i < values.size(); ++i) {
in.insert(values[i]);
out[i % 3 == 0? 0 : 1].insert(values[i]);
}
raii::reset_counts();
thread_runner(values, [&](boost::span<value_type> s) {
std::size_t br1 = 0, br2 = 0, br3 = 0;
for(auto const& v: s) {
typename X::node_type nh;
while (nh.empty()) {
switch (br1++ % 3) {
case 0:
nh = in.extract(test::get_key<X>(v));
BOOST_ASSERT(!nh.empty());
break;
case 1:
nh = in.extract_if(
test::get_key<X>(v), [&](arg_visit_type& v2) {
BOOST_ASSERT(test::get_key<X>(v) == test::get_key<X>(v2));
(void)v2;
return false;
});
BOOST_ASSERT(nh.empty());
break;
case 2: default:
nh = in.extract_if(
test::get_key<X>(v), [&](arg_visit_type& v2) {
BOOST_ASSERT(test::get_key<X>(v) == test::get_key<X>(v2));
(void)v2;
return true;
});
BOOST_ASSERT(!nh.empty());
break;
}
}
BOOST_ASSERT(nh.get_allocator() == in.get_allocator());
while (!nh.empty()) {
auto& o = out[br2++ % out.size()];
typename X::insert_return_type r;
switch (br3++ % 3) {
case 0:
r = o.insert(std::move(nh));
break;
case 1:
r = o.insert_or_visit(
std::move(nh), [&](arg_visit_type& v2) {
BOOST_ASSERT(test::get_key<X>(v) == test::get_key<X>(v2));
(void)v2;
});
break;
case 2: default:
r = o.insert_or_cvisit(
std::move(nh), [&](arg_visit_type const& v2) {
BOOST_ASSERT(test::get_key<X>(v) == test::get_key<X>(v2));
(void)v2;
});
break;
}
BOOST_ASSERT(r.inserted || !r.node.empty());
nh = std::move(r.node);
}
}
});
BOOST_TEST_EQ(in.size(), 0u);
BOOST_TEST_EQ(out[0].size() + out[1].size(), 2 * values.size());
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, 0u);
BOOST_TEST_EQ(raii::move_constructor, 0u);
BOOST_TEST_EQ(raii::destructor, 0u);
}
template <class X>
void insert_empty_node_tests(X*)
{
using value_type = typename X::value_type;
using node_type = typename X::node_type ;
X x;
{
node_type nh;
auto r = x.insert(std::move(nh));
BOOST_TEST(!r.inserted);
BOOST_TEST(r.node.empty());
}
{
node_type nh;
auto r = x.insert_or_visit(std::move(nh), [](value_type const&) {});
BOOST_TEST(!r.inserted);
BOOST_TEST(r.node.empty());
}
{
node_type nh;
auto r = x.insert_or_cvisit(std::move(nh), [](value_type const&) {});
BOOST_TEST(!r.inserted);
BOOST_TEST(r.node.empty());
}
}
} // namespace
// clang-format off
UNORDERED_TEST(
extract_insert_tests,
((test_node_map)(test_node_set))
((value_type_generator_factory)))
UNORDERED_TEST(
insert_empty_node_tests,
((test_node_map)(test_node_set)))
// clang-format on
RUN_TESTS()
+56 -6
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/config/workaround.hpp>
#include <boost/unordered/concurrent_flat_map_fwd.hpp>
#include <boost/unordered/concurrent_flat_set_fwd.hpp>
#include <boost/unordered/concurrent_node_map_fwd.hpp>
#include <boost/unordered/concurrent_node_set_fwd.hpp>
#include <limits>
test::seed_t initialize_seed{32304628};
@@ -36,6 +38,27 @@ bool unequal_call(boost::unordered::concurrent_flat_map<T, T>& x1,
return x1 != x2;
}
template <class T>
void swap_call(boost::unordered::concurrent_node_map<T, T>& x1,
boost::unordered::concurrent_node_map<T, T>& x2)
{
swap(x1, x2);
}
template <class T>
bool equal_call(boost::unordered::concurrent_node_map<T, T>& x1,
boost::unordered::concurrent_node_map<T, T>& x2)
{
return x1 == x2;
}
template <class T>
bool unequal_call(boost::unordered::concurrent_node_map<T, T>& x1,
boost::unordered::concurrent_node_map<T, T>& x2)
{
return x1 != x2;
}
template <class T>
void swap_call(boost::unordered::concurrent_flat_set<T>& x1,
boost::unordered::concurrent_flat_set<T>& x2)
@@ -57,14 +80,41 @@ bool unequal_call(boost::unordered::concurrent_flat_set<T>& x1,
return x1 != x2;
}
template <class T>
void swap_call(boost::unordered::concurrent_node_set<T>& x1,
boost::unordered::concurrent_node_set<T>& x2)
{
swap(x1, x2);
}
template <class T>
bool equal_call(boost::unordered::concurrent_node_set<T>& x1,
boost::unordered::concurrent_node_set<T>& x2)
{
return x1 == x2;
}
template <class T>
bool unequal_call(boost::unordered::concurrent_node_set<T>& x1,
boost::unordered::concurrent_node_set<T>& x2)
{
return x1 != x2;
}
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
using map_type = boost::unordered::concurrent_flat_map<int, int>;
using set_type = boost::unordered::concurrent_flat_map<int, int>;
using node_map_type = boost::unordered::concurrent_node_map<int, int>;
using set_type = boost::unordered::concurrent_flat_set<int>;
using node_set_type = boost::unordered::concurrent_node_set<int>;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
template <typename X>
void fwd_swap_call(X*)
@@ -106,19 +156,19 @@ void max_size(X*)
// clang-format off
UNORDERED_TEST(
fwd_swap_call,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
fwd_equal_call,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
fwd_unequal_call,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
max_size,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
// clang-format on
RUN_TESTS()
+21 -2
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Copyright (C) 2024 Braden Ganetsky
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -147,9 +147,15 @@ public:
cfoa_ptr(std::nullptr_t) : p_(nullptr){};
template <class U> using rebind = cfoa_ptr<U>;
operator bool() const { return !!p_; }
template <typename Q = T>
Q& operator*() const noexcept { return *p_; }
T* operator->() const noexcept { return p_; }
static cfoa_ptr<T> pointer_to(element_type& r) { return {std::addressof(r)}; }
template<typename Q = T>
static cfoa_ptr<Q> pointer_to(Q& r) { return {std::addressof(r)}; }
};
template <class T> struct stateful_allocator
@@ -670,4 +676,17 @@ public:
fancy_allocator& operator=(fancy_allocator const&) { return *this; }
};
namespace boost {
template <> struct pointer_traits<void_ptr>
{
template <class U> struct rebind_to
{
typedef ptr<U> type;
};
template<class U>
using rebind=typename rebind_to<U>::type;
};
} // namespace boost
#endif // BOOST_UNORDERED_TEST_CFOA_HELPERS_HPP
+100 -21
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,6 +8,8 @@
#include <boost/config.hpp>
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -179,8 +181,15 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, 2 * x.size());
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::copy_assignment, values.size() - x.size());
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
@@ -198,7 +207,14 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, x.size());
BOOST_TEST_GT(raii::move_constructor, x.size()); // rehashing
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, x.size());
}
else{
BOOST_TEST_GT(raii::move_constructor, x.size()); // rehashing
}
BOOST_TEST_EQ(raii::copy_assignment, 0u);
BOOST_TEST_EQ(raii::move_assignment, values.size() - x.size());
}
@@ -216,7 +232,14 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, x.size());
BOOST_TEST_GT(raii::move_constructor, x.size()); // rehashing
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, x.size());
}
else{
BOOST_TEST_GT(raii::move_constructor, x.size()); // rehashing
}
BOOST_TEST_EQ(raii::copy_assignment, values.size() - x.size());
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
@@ -234,7 +257,14 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, 0u);
BOOST_TEST_GE(raii::move_constructor, 2 * x.size());
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 2 * x.size());
}
else{
BOOST_TEST_GE(raii::move_constructor, 2 * x.size()); // rehashing
}
BOOST_TEST_EQ(raii::copy_assignment, 0u);
BOOST_TEST_EQ(raii::move_assignment, values.size() - x.size());
}
@@ -260,7 +290,14 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, x.size());
BOOST_TEST_EQ(raii::copy_constructor, x.size());
BOOST_TEST_GT(raii::move_constructor, x.size()); // rehashing
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
BOOST_TEST_GT(raii::move_constructor, 0u); // rehashing
}
BOOST_TEST_EQ(raii::copy_assignment, values.size() - x.size());
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
@@ -284,7 +321,14 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, x.size());
BOOST_TEST_EQ(raii::copy_constructor, 0u);
BOOST_TEST_GT(raii::move_constructor, 2 * x.size()); // rehashing
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, x.size());
}
else{
BOOST_TEST_GT(raii::move_constructor, x.size()); // rehashing
}
BOOST_TEST_EQ(raii::copy_assignment, 0u);
BOOST_TEST_EQ(raii::move_assignment, values.size() - x.size());
}
@@ -319,8 +363,15 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(
raii::copy_constructor, value_type_cardinality * x.size());
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
} lvalue_insert_or_cvisit;
@@ -360,8 +411,15 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, 0u);
BOOST_TEST_EQ(raii::copy_constructor, value_type_cardinality * x.size());
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::move_assignment, 0u);
}
} lvalue_insert_or_visit;
@@ -665,12 +723,14 @@ namespace {
}
}
UNORDERED_AUTO_TEST (insert_sfinae_test) {
template <class X>
void insert_map_sfinae_test(X*)
{
// mostly a compile-time tests to ensure that there's no ambiguity when a
// user does this
using value_type =
typename boost::unordered::concurrent_flat_map<raii, raii>::value_type;
boost::unordered::concurrent_flat_map<raii, raii> x;
using value_type = typename X::value_type;
X x;
x.insert({1, 2});
x.insert_or_visit({2, 3}, [](value_type&) {});
@@ -684,11 +744,23 @@ namespace {
std::equal_to<raii>, fancy_allocator<std::pair<raii const, raii> > >*
fancy_map;
boost::unordered::concurrent_node_map<raii, raii>* node_map;
boost::unordered::concurrent_node_map<raii, raii, transp_hash,
transp_key_equal>* trans_node_map;
boost::unordered::concurrent_node_map<raii, raii, boost::hash<raii>,
std::equal_to<raii>, fancy_allocator<std::pair<raii const, raii> > >*
fancy_node_map;
boost::unordered::concurrent_flat_set<raii>* set;
boost::unordered::concurrent_flat_set<raii, boost::hash<raii>,
std::equal_to<raii>, fancy_allocator<std::pair<raii const, raii> > >*
std::equal_to<raii>, fancy_allocator<raii> >*
fancy_set;
boost::unordered::concurrent_node_set<raii>* node_set;
boost::unordered::concurrent_node_set<raii, boost::hash<raii>,
std::equal_to<raii>, fancy_allocator<raii> >*
fancy_node_set;
std::initializer_list<std::pair<raii const, raii> > map_init_list{
{raii{0}, raii{0}},
{raii{1}, raii{1}},
@@ -740,7 +812,9 @@ namespace {
};
auto map_and_init_list=std::make_pair(map,map_init_list);
auto node_map_and_init_list=std::make_pair(node_map,map_init_list);
auto set_and_init_list=std::make_pair(set,set_init_list);
auto node_set_and_init_list=std::make_pair(node_set,set_init_list);
} // namespace
@@ -751,11 +825,12 @@ using test::sequential;
// clang-format off
UNORDERED_TEST(
insert_initializer_list,
((map_and_init_list)(set_and_init_list)))
((map_and_init_list)(node_map_and_init_list)(set_and_init_list)))
UNORDERED_TEST(
insert,
((map)(fancy_map)(set)(fancy_set))
((map)(fancy_map)(node_map)(fancy_node_map)
(set)(fancy_set)(node_set)(fancy_node_set))
((value_type_generator_factory)(init_type_generator_factory))
((lvalue_inserter)(rvalue_inserter)(iterator_range_inserter)
(norehash_lvalue_inserter)(norehash_rvalue_inserter)
@@ -766,7 +841,7 @@ UNORDERED_TEST(
UNORDERED_TEST(
insert,
((map))
((map)(node_map))
((init_type_generator_factory))
((lvalue_insert_or_assign_copy_assign)(lvalue_insert_or_assign_move_assign)
(rvalue_insert_or_assign_copy_assign)(rvalue_insert_or_assign_move_assign))
@@ -774,10 +849,14 @@ UNORDERED_TEST(
UNORDERED_TEST(
insert,
((trans_map))
((trans_map)(trans_node_map))
((init_type_generator_factory))
((trans_insert_or_assign_copy_assign)(trans_insert_or_assign_move_assign))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
insert_map_sfinae_test,
((map)(node_map)))
// clang-format on
RUN_TESTS()
+45 -10
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
test::seed_t initialize_seed{402031699};
@@ -23,19 +25,38 @@ using map2_type = boost::unordered::concurrent_flat_map<raii, raii,
std::hash<raii>, std::equal_to<raii>,
stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii,
hasher, key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map2_type = boost::unordered::concurrent_node_map<raii, raii,
std::hash<raii>, std::equal_to<raii>,
stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using set2_type = boost::unordered::concurrent_flat_set<raii, std::hash<raii>,
std::equal_to<raii>, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set2_type = boost::unordered::concurrent_node_set<raii, std::hash<raii>,
std::equal_to<raii>, stateful_allocator<raii> >;
map_type* test_map;
map2_type* test_map2;
auto test_maps=std::make_pair(test_map,test_map2);
node_map_type* test_node_map;
node_map2_type* test_node_map2;
auto test_node_maps=std::make_pair(test_node_map,test_node_map2);
set_type* test_set;
set2_type* test_set2;
auto test_sets=std::make_pair(test_set,test_set2);
node_set_type* test_node_set;
node_set2_type* test_node_set2;
auto test_node_sets=std::make_pair(test_node_set,test_node_set2);
struct
{
template <class X1, class X2>
@@ -91,9 +112,16 @@ namespace {
});
BOOST_TEST_EQ(raii::copy_constructor, old_cc + expected_copies);
BOOST_TEST_EQ(
raii::move_constructor,
value_type_cardinality * reference_cont.size());
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
BOOST_TEST_EQ(
raii::move_constructor,
value_type_cardinality * reference_cont.size());
}
BOOST_TEST_EQ(+num_merged, reference_cont.size());
test_fuzzy_matches_reference(x, reference_cont, rg);
@@ -210,10 +238,17 @@ namespace {
t3.join();
if (num_merges > 0) {
// num merges is 0 most commonly in the cast of the limited_range
// generator as both maps will contains keys from 0 to 99
BOOST_TEST_EQ(
+raii::move_constructor, value_type_cardinality * num_merges);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// num merges is 0 most commonly in the cast of the limited_range
// generator as both maps will contains keys from 0 to 99
BOOST_TEST_EQ(
raii::move_constructor, value_type_cardinality * num_merges);
}
BOOST_TEST_GE(call_count, 1u);
}
@@ -229,14 +264,14 @@ namespace {
// clang-format off
UNORDERED_TEST(
merge_tests,
((test_maps)(test_sets))
((test_maps)(test_node_maps)(test_sets)(test_node_sets))
((lvalue_merge)(rvalue_merge))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
insert_and_merge_tests,
((test_maps)(test_sets))
((test_maps)(test_node_maps)(test_sets)(test_node_sets))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
// clang-format on
@@ -0,0 +1,6 @@
// Copyright 2024 Joaquin M Lopez Munoz.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_UNORDERED_CFOA_TESTS
#include "../unordered/node_handle_allocator_tests.cpp"
+2
View File
@@ -5,4 +5,6 @@
#define BOOST_UNORDERED_CFOA_TESTS
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include "../unordered/pmr_allocator_tests.cpp"
+8 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2023 Joaquin M Lopez Munoz
// Copyright 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -32,15 +32,21 @@ namespace boost {
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/core/lightweight_test.hpp>
using test::default_generator;
using map_type = boost::unordered::concurrent_flat_map<raii, raii>;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii>;
using set_type = boost::unordered::concurrent_flat_set<raii>;
using node_set_type = boost::unordered::concurrent_node_set<raii>;
map_type* test_map;
map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
template<typename F>
void detect_reentrancy(F f)
@@ -105,7 +111,7 @@ namespace {
// clang-format off
UNORDERED_TEST(
reentrancy_tests,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)))
// clang-format on
+14 -4
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
using test::default_generator;
using test::limited_range;
@@ -18,11 +20,19 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
map_type* test_map;
node_map_type* test_node_map;
set_type* test_set;
node_set_type* test_node_set;
namespace {
test::seed_t initialize_seed{748775921};
@@ -187,15 +197,15 @@ namespace {
// clang-format off
UNORDERED_TEST(
rehash_no_insert,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
reserve_no_insert,
((test_map)(test_set)))
((test_map)(test_node_map)(test_set)(test_node_set)))
UNORDERED_TEST(
insert_and_erase_with_rehash,
((test_map)(test_set))
((test_map)(test_node_map)(test_set)(test_node_set))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
// clang-format on
+8 -2
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -12,6 +12,8 @@
#include <boost/serialization/nvp.hpp>
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
namespace {
@@ -70,11 +72,15 @@ namespace {
boost::concurrent_flat_map<
test::object, test::object, test::hash, test::equal_to>* test_flat_map;
boost::concurrent_node_map<
test::object, test::object, test::hash, test::equal_to>* test_node_map;
boost::concurrent_flat_set<
test::object, test::hash, test::equal_to>* test_flat_set;
boost::concurrent_node_set<
test::object, test::hash, test::equal_to>* test_node_set;
UNORDERED_TEST(serialization_tests,
((test_flat_map)(test_flat_set))
((test_flat_map)(test_node_map)(test_flat_set)(test_node_set))
((text_archive)(xml_archive))
((default_generator)))
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2024 Joaquin M Lopez Muoz.
// Copyright 2024 Joaquin M Lopez Munoz.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+18 -3
View File
@@ -1,5 +1,5 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2023 Joaquin M Lopez Munoz
// Copyright (C) 2023-2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,6 +7,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
test::seed_t initialize_seed{996130204};
@@ -62,9 +64,15 @@ using key_equal = stateful_key_equal;
using map_type = boost::unordered::concurrent_flat_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using node_map_type = boost::unordered::concurrent_node_map<raii, raii, hasher,
key_equal, stateful_allocator<std::pair<raii const, raii> > >;
using set_type = boost::unordered::concurrent_flat_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
using node_set_type = boost::unordered::concurrent_node_set<raii, hasher,
key_equal, stateful_allocator<raii> >;
template <class T> struct is_nothrow_member_swappable
{
static bool const value =
@@ -293,21 +301,28 @@ namespace {
map_type* map;
replace_allocator<map_type, pocs_allocator>* pocs_map;
node_map_type* node_map;
replace_allocator<node_map_type, pocs_allocator>* pocs_node_map;
set_type* set;
replace_allocator<set_type, pocs_allocator>* pocs_set;
node_set_type* node_set;
replace_allocator<node_set_type, pocs_allocator>* pocs_node_set;
} // namespace
// clang-format off
UNORDERED_TEST(
swap_tests,
((map)(pocs_map)(set)(pocs_set))
((map)(pocs_map)(node_map)(pocs_node_map)
(set)(pocs_set)(node_set)(pocs_node_set))
((member_fn_swap)(free_fn_swap))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(insert_and_swap,
((map)(set))
((map)(node_map)(set)(node_set))
((member_fn_swap)(free_fn_swap))
((value_type_generator_factory))
((default_generator)(sequential)(limited_range)))
+38 -8
View File
@@ -1,10 +1,12 @@
// Copyright (C) 2023 Christian Mazakas
// Copyright (C) 2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "helpers.hpp"
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -161,8 +163,15 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, x.size());
BOOST_TEST_EQ(raii::copy_constructor, x.size());
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::move_assignment, 0u);
BOOST_TEST_EQ(raii::copy_assignment, 0u);
}
@@ -194,8 +203,15 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, x.size());
BOOST_TEST_EQ(raii::copy_constructor, x.size());
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
// don't check move construction count here because of rehashing
BOOST_TEST_GT(raii::move_constructor, 0u);
}
BOOST_TEST_EQ(raii::move_assignment, 0u);
BOOST_TEST_EQ(raii::copy_assignment, 0u);
}
@@ -229,7 +245,12 @@ namespace {
if (std::is_same<T, typename X::value_type>::value) {
BOOST_TEST_EQ(raii::copy_constructor, x.size());
BOOST_TEST_GE(raii::move_constructor, x.size());
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
BOOST_TEST_GE(raii::move_constructor, x.size());
}
} else {
BOOST_TEST_EQ(raii::copy_constructor, 0u);
BOOST_TEST_GE(raii::move_constructor, x.size());
@@ -264,7 +285,12 @@ namespace {
BOOST_TEST_EQ(raii::default_constructor, x.size());
if (std::is_same<T, typename X::value_type>::value) {
BOOST_TEST_EQ(raii::copy_constructor, x.size());
BOOST_TEST_GE(raii::move_constructor, x.size());
if (is_container_node_based<X>::value) {
BOOST_TEST_EQ(raii::move_constructor, 0u);
}
else{
BOOST_TEST_GE(raii::move_constructor, x.size());
}
} else {
BOOST_TEST_EQ(raii::copy_constructor, 0u);
BOOST_TEST_GE(raii::move_constructor, x.size());
@@ -367,6 +393,10 @@ namespace {
boost::unordered::concurrent_flat_map<raii, raii, transp_hash,
transp_key_equal>* transp_map;
boost::unordered::concurrent_node_map<raii, raii>* node_map;
boost::unordered::concurrent_node_map<raii, raii, transp_hash,
transp_key_equal>* transp_node_map;
} // namespace
using test::default_generator;
@@ -379,7 +409,7 @@ value_generator<std::pair<raii, raii> > init_type_generator;
// clang-format off
UNORDERED_TEST(
try_emplace,
((map))
((map)(node_map))
((value_type_generator)(init_type_generator))
((lvalue_try_emplacer)(norehash_lvalue_try_emplacer)
(rvalue_try_emplacer)(norehash_rvalue_try_emplacer)
@@ -389,7 +419,7 @@ UNORDERED_TEST(
UNORDERED_TEST(
try_emplace,
((transp_map))
((transp_map)(transp_node_map))
((init_type_generator))
((transp_try_emplace)(norehash_transp_try_emplace)
(transp_try_emplace_or_cvisit)(transp_try_emplace_or_visit))
+19 -8
View File
@@ -17,6 +17,8 @@
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/compat/latch.hpp>
#include <boost/core/ignore_unused.hpp>
@@ -971,9 +973,15 @@ namespace {
boost::unordered::concurrent_flat_map<raii, raii>* map;
boost::unordered::concurrent_flat_map<raii, raii, transp_hash,
transp_key_equal>* transp_map;
boost::unordered::concurrent_node_map<raii, raii>* node_map;
boost::unordered::concurrent_node_map<raii, raii, transp_hash,
transp_key_equal>* transp_node_map;
boost::unordered::concurrent_flat_set<raii>* set;
boost::unordered::concurrent_flat_set<raii, transp_hash,
transp_key_equal>* transp_set;
boost::unordered::concurrent_node_set<raii>* node_set;
boost::unordered::concurrent_node_set<raii, transp_hash,
transp_key_equal>* transp_node_set;
struct mutable_pair
{
@@ -1114,7 +1122,9 @@ namespace {
}
boost::concurrent_flat_set<
mutable_pair, mutable_pair_hash, mutable_pair_equal_to>* mutable_set;
mutable_pair, mutable_pair_hash, mutable_pair_equal_to>* mutable_set;
boost::concurrent_node_set<
mutable_pair, mutable_pair_hash, mutable_pair_equal_to>* mutable_node_set;
} // namespace
@@ -1126,7 +1136,7 @@ using test::sequential;
UNORDERED_TEST(
visit,
((map)(set))
((map)(node_map)(set)(node_set))
((value_type_generator_factory)(init_type_generator_factory))
((lvalue_visitor)(visit_all)(visit_while)(exec_policy_visit_all)
(exec_policy_visit_while))
@@ -1134,28 +1144,29 @@ UNORDERED_TEST(
UNORDERED_TEST(
visit,
((transp_map)(transp_set))
((transp_map)(transp_node_map)(transp_set)(transp_node_set))
((value_type_generator_factory)(init_type_generator_factory))
((transp_visitor))
((default_generator)(sequential)(limited_range)))
UNORDERED_TEST(
empty_visit,
((map)(transp_map)(set)(transp_set))
((map)(transp_map)(node_map)(transp_node_map)
(set)(transp_set)(node_set)(transp_node_set))
((value_type_generator_factory)(init_type_generator_factory))
((default_generator)(sequential)(limited_range))
)
UNORDERED_TEST(
insert_and_visit,
((map)(set))
((map)(node_map)(set)(node_set))
((value_type_generator_factory))
((sequential))
)
UNORDERED_TEST(
bulk_visit,
((map)(set))
((map)(node_map)(set)(node_set))
((regular_key_extract))
((value_type_generator_factory))
((sequential))
@@ -1163,7 +1174,7 @@ UNORDERED_TEST(
UNORDERED_TEST(
bulk_visit,
((transp_map)(transp_set))
((transp_map)(transp_node_map)(transp_set)(transp_node_set))
((transp_key_extract))
((value_type_generator_factory))
((sequential))
@@ -1173,7 +1184,7 @@ UNORDERED_TEST(
UNORDERED_TEST(
exclusive_access_set_visit,
((mutable_set))
((mutable_set)(mutable_node_set))
)
// clang-format on
+9 -1
View File
@@ -20,6 +20,8 @@
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
#include <boost/unordered/unordered_flat_set.hpp>
#include <boost/unordered/unordered_map.hpp>
@@ -61,8 +63,12 @@ template <class Tester> void visualization_test(Tester& tester)
auto cfoa_flat_map_ptr = tester.template construct_map<boost::concurrent_flat_map>();
auto cfoa_flat_set_ptr = tester.template construct_set<boost::concurrent_flat_set>();
auto cfoa_node_map_ptr = tester.template construct_map<boost::concurrent_node_map>();
auto cfoa_node_set_ptr = tester.template construct_set<boost::concurrent_node_set>();
auto& cfoa_flat_map = *cfoa_flat_map_ptr;
auto& cfoa_flat_set = *cfoa_flat_set_ptr;
auto& cfoa_node_map = *cfoa_node_map_ptr;
auto& cfoa_node_set = *cfoa_node_set_ptr;
// clang-format on
for (int i = 0; i < 5; ++i) {
@@ -75,6 +81,7 @@ template <class Tester> void visualization_test(Tester& tester)
foa_flat_map.emplace(str, num);
foa_node_map.emplace(str, num);
cfoa_flat_map.emplace(str, num);
cfoa_node_map.emplace(str, num);
fca_set.emplace(str);
fca_multiset.emplace(str);
@@ -82,6 +89,7 @@ template <class Tester> void visualization_test(Tester& tester)
foa_flat_set.emplace(str);
foa_node_set.emplace(str);
cfoa_flat_set.emplace(str);
cfoa_node_set.emplace(str);
}
auto fca_map_begin = fca_map.begin();
@@ -102,7 +110,7 @@ template <class Tester> void visualization_test(Tester& tester)
auto foa_node_set_begin = foa_node_set.begin();
auto foa_node_set_end = foa_node_set.end();
use(cfoa_flat_map, cfoa_flat_set);
use(cfoa_flat_map, cfoa_flat_set, cfoa_node_map, cfoa_node_set);
use(fca_map_begin, fca_map_end, fca_multimap_begin, fca_multimap_end,
fca_set_begin, fca_set_end, fca_multiset_begin, fca_multiset_end);
use(foa_flat_map_begin, foa_flat_map_end, foa_flat_set_begin,
+19 -2
View File
@@ -1,14 +1,17 @@
// Copyright 2024 Joaquin M Lopez Muoz.
// Copyright 2024 Joaquin M Lopez Munoz.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at htT://www.boost.org/LICENSE_1_0.txt)
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifdef BOOST_UNORDERED_CFOA_TESTS
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#else
#include "../helpers/unordered.hpp"
#endif
#include "../helpers/helpers.hpp"
#include "../helpers/test.hpp"
#include <boost/type_traits/make_void.hpp>
#include <memory>
@@ -62,7 +65,16 @@ template <class Container> void test_explicit_alloc_ctor_extract(
template <class Container> void test_explicit_alloc_ctor_extract(
Container& c, std::true_type)
{
#ifdef BOOST_UNORDERED_CFOA_TESTS
typename Container::key_type k;
c.cvisit_while([&](typename Container::value_type const & x) {
k = test::get_key<Container>(x);
return false;
});
auto n = c.extract(k);
#else
auto n = c.extract(c.begin());
#endif
c.insert(std::move(n));
n = c.extract(typename Container::key_type());
c.insert(std::move(n));
@@ -122,8 +134,13 @@ UNORDERED_AUTO_TEST (explicit_alloc_ctor) {
test_explicit_alloc_ctor<boost::concurrent_flat_map<int, int,
boost::hash<int>, std::equal_to<int>,
explicit_allocator<std::pair<const int, int> > > >();
test_explicit_alloc_ctor<boost::concurrent_node_map<int, int,
boost::hash<int>, std::equal_to<int>,
explicit_allocator<std::pair<const int, int> > > >();
test_explicit_alloc_ctor<boost::concurrent_flat_set<
int, boost::hash<int>, std::equal_to<int>, explicit_allocator<int> > >();
test_explicit_alloc_ctor<boost::concurrent_node_set<
int, boost::hash<int>, std::equal_to<int>, explicit_allocator<int> > >();
#elif defined(BOOST_UNORDERED_FOA_TESTS)
test_explicit_alloc_ctor<boost::unordered_flat_map<int, int,
boost::hash<int>, std::equal_to<int>,
@@ -0,0 +1,213 @@
// Copyright (C) 2024 Joaquin M Lopez Munoz
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined(BOOST_GCC)
// Spurious maybe-uninitialized warnings with allocators contained
// in node handles.
// Maybe related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108230
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#ifdef BOOST_UNORDERED_CFOA_TESTS
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#else
#include "../helpers/unordered.hpp"
#endif
#include "../helpers/test.hpp"
#include <boost/config/workaround.hpp>
#include <boost/core/allocator_access.hpp>
#include <memory>
#include <type_traits>
namespace {
template <class T> struct nonassignable_allocator
{
using value_type = T;
nonassignable_allocator() = default;
nonassignable_allocator(nonassignable_allocator const&) = default;
template <class U>
nonassignable_allocator(nonassignable_allocator<U> const&) {}
nonassignable_allocator& operator=(nonassignable_allocator const&) = delete;
T* allocate(std::size_t n)
{
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t) { ::operator delete(p); }
bool operator==(nonassignable_allocator const&) const { return true; }
bool operator!=(nonassignable_allocator const&) const { return false; }
};
template <class T> struct pocx_allocator
{
int x_;
using value_type = T;
using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
using propagate_on_container_swap = std::true_type;
pocx_allocator() : x_{-1} {}
pocx_allocator(pocx_allocator const&) = default;
pocx_allocator(int const x) : x_{x} {}
template <class U>
pocx_allocator(pocx_allocator<U> const& rhs) : x_{rhs.x_}
{
}
pocx_allocator& operator=(pocx_allocator const&) = default;
T* allocate(std::size_t n)
{
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t) { ::operator delete(p); }
bool operator==(pocx_allocator const& rhs) const { return x_ == rhs.x_; }
bool operator!=(pocx_allocator const& rhs) const { return x_ != rhs.x_; }
};
template <typename Container, typename Allocator>
struct replace_allocator_impl;
template <typename Container, typename Allocator>
using replace_allocator =
typename replace_allocator_impl<Container, Allocator>::type;
template <
typename K, typename H, typename P, typename A,
template <typename, typename, typename, typename> class Set,
typename Allocator
>
struct replace_allocator_impl<Set<K, H, P, A>, Allocator>
{
using type = Set<
K, H, P, boost::allocator_rebind_t<Allocator, K> >;
};
template <
typename K, typename H, typename T, typename P, typename A,
template <typename, typename, typename, typename, typename> class Map,
typename Allocator
>
struct replace_allocator_impl<Map<K, T, H, P, A>, Allocator>
{
using type = Map<
K, T, H, P,
boost::allocator_rebind_t<Allocator, std::pair<K const, T> > >;
};
template<typename X, typename Allocator>
void node_handle_allocator_tests(
X*, std::pair<Allocator, Allocator> allocators)
{
using value_type = typename X::value_type;
using replaced_allocator_container = replace_allocator<X, Allocator>;
using node_type = typename replaced_allocator_container::node_type;
replaced_allocator_container x1(allocators.first);
node_type nh;
x1.emplace(value_type());
nh = x1.extract(0);
BOOST_TEST(!nh.empty());
BOOST_TEST(nh.get_allocator() == x1.get_allocator());
replaced_allocator_container x2(allocators.second);
x2.emplace(value_type());
nh = x2.extract(0);
BOOST_TEST(!nh.empty());
BOOST_TEST(nh.get_allocator() == x2.get_allocator());
}
template<typename X, typename Allocator>
void node_handle_allocator_swap_tests(
X*, std::pair<Allocator, Allocator> allocators)
{
using value_type = typename X::value_type;
using replaced_allocator_container = replace_allocator<X, Allocator>;
using node_type = typename replaced_allocator_container::node_type;
replaced_allocator_container x1(allocators.first), x2(allocators.second);
x1.emplace(value_type());
x2.emplace(value_type());
node_type nh1, nh2;
nh1 = x1.extract(0);
swap(nh1, nh2);
BOOST_TEST(nh1.empty());
BOOST_TEST(!nh2.empty());
BOOST_TEST(nh2.get_allocator() == x1.get_allocator());
nh1 = x2.extract(0);
swap(nh1, nh2);
BOOST_TEST(!nh1.empty());
BOOST_TEST(nh1.get_allocator() == x1.get_allocator());
BOOST_TEST(!nh2.empty());
BOOST_TEST(nh2.get_allocator() == x2.get_allocator());
}
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
#pragma warning(push)
#pragma warning(disable : 4592) // symbol will be dynamically initialized
#endif
std::pair<
std::allocator<int>, std::allocator<int> > test_std_allocators({},{});
std::pair<
nonassignable_allocator<int>,
nonassignable_allocator<int> > test_nonassignable_allocators({},{});
std::pair<
pocx_allocator<int>, pocx_allocator<int> > test_pocx_allocators(5,6);
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
#pragma warning(pop) // C4592
#endif
#if defined(BOOST_UNORDERED_FOA_TESTS)
boost::unordered_node_map<int, int>* test_map;
boost::unordered_node_set<int>* test_set;
#elif defined(BOOST_UNORDERED_CFOA_TESTS)
boost::concurrent_node_map<int, int>* test_map;
boost::concurrent_node_set<int>* test_set;
#else
boost::unordered_map<int, int>* test_map;
boost::unordered_set<int>* test_set;
#endif
} // namespace
// clang-format off
UNORDERED_TEST(
node_handle_allocator_tests,
((test_map)(test_set))
((test_std_allocators)(test_nonassignable_allocators)
(test_pocx_allocators)))
UNORDERED_TEST(
node_handle_allocator_swap_tests,
((test_map)(test_set))
((test_std_allocators)(test_pocx_allocators)))
// clang-format on
RUN_TESTS()
+12 -1
View File
@@ -33,12 +33,23 @@ namespace pmr_allocator_tests {
test_string_flat_map;
static boost::unordered::pmr::concurrent_flat_map<pmr_string, pmr_string>*
test_pmr_string_flat_map;
static boost::unordered::pmr::concurrent_node_map<std::string, std::string>*
test_string_node_map;
static boost::unordered::pmr::concurrent_node_map<pmr_string, pmr_string>*
test_pmr_string_node_map;
static boost::unordered::pmr::concurrent_flat_set<std::string>*
test_string_flat_set;
static boost::unordered::pmr::concurrent_flat_set<pmr_string>*
test_pmr_string_flat_set;
static boost::unordered::pmr::concurrent_node_set<std::string>*
test_string_node_set;
static boost::unordered::pmr::concurrent_node_set<pmr_string>*
test_pmr_string_node_set;
#define PMR_ALLOCATOR_TESTS_ARGS \
((test_string_flat_map)(test_pmr_string_flat_map)(test_string_flat_set)(test_pmr_string_flat_set))
((test_string_flat_map)(test_pmr_string_flat_map) \
(test_string_node_map)(test_pmr_string_node_map) \
(test_string_flat_set)(test_pmr_string_flat_set) \
(test_string_node_set)(test_pmr_string_node_set))
#elif defined(BOOST_UNORDERED_FOA_TESTS)
static boost::unordered::pmr::unordered_flat_map<std::string, std::string>*
test_string_flat_map;
+37 -15
View File
@@ -1,4 +1,4 @@
// Copyright 2024 Joaquin M Lopez Muoz.
// Copyright 2024 Joaquin M Lopez Munoz.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,8 +7,12 @@
#ifdef BOOST_UNORDERED_CFOA_TESTS
#include <boost/unordered/concurrent_flat_map.hpp>
#include <boost/unordered/concurrent_flat_set.hpp>
#include <boost/unordered/concurrent_node_map.hpp>
#include <boost/unordered/concurrent_node_set.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
#include <boost/unordered/unordered_flat_set.hpp>
#include <boost/unordered/unordered_node_map.hpp>
#include <boost/unordered/unordered_node_set.hpp>
#include "../cfoa/helpers.hpp"
#else
#include "../helpers/unordered.hpp"
@@ -19,6 +23,7 @@
#include "../helpers/test.hpp"
#include <boost/assert.hpp>
#include <boost/core/make_span.hpp>
#include <cmath>
#include <cstring>
template <class T> struct unequal_allocator
@@ -45,16 +50,20 @@ template <class T> struct unequal_allocator
int n_;
};
bool exact_same(double x, double y)
bool esentially_same(double x, double y)
{
return std::memcmp(
reinterpret_cast<void*>(&x), reinterpret_cast<void*>(&y),
sizeof(double))==0;
// Some optimizer-related issues in GCC X86 result in last-bit differences
// on doubles that should otherwise be identical.
// https://stackoverflow.com/a/253874/213114
static constexpr double epsilon = 1.0E-6;
return fabs(x - y) <= ( (fabs(x) > fabs(y) ? fabs(x) : fabs(y)) * epsilon);
}
bool not_exact_same(double x, double y)
bool not_esentially_same(double x, double y)
{
return !exact_same(x, y);
return !esentially_same(x, y);
}
enum check_stats_contition
@@ -69,19 +78,19 @@ void check_stat(const Stats& s, check_stats_contition cond)
{
switch (cond) {
case stats_empty:
BOOST_TEST(exact_same(s.average, 0.0));
BOOST_TEST(exact_same(s.variance, 0.0));
BOOST_TEST(exact_same(s.deviation, 0.0));
BOOST_TEST(esentially_same(s.average, 0.0));
BOOST_TEST(esentially_same(s.variance, 0.0));
BOOST_TEST(esentially_same(s.deviation, 0.0));
break;
case stats_full:
BOOST_TEST_GT(s.average, 0.0);
if(not_exact_same(s.variance, 0.0)) {
if(not_esentially_same(s.variance, 0.0)) {
BOOST_TEST_GT(s.variance, 0.0);
BOOST_TEST_GT(s.deviation, 0.0);
}
break;
case stats_mostly_full:
if(not_exact_same(s.variance, 0.0)) {
if(not_esentially_same(s.variance, 0.0)) {
BOOST_TEST_GT(s.average, 0.0);
BOOST_TEST_GT(s.variance, 0.0);
BOOST_TEST_GT(s.deviation, 0.0);
@@ -94,9 +103,9 @@ void check_stat(const Stats& s, check_stats_contition cond)
template <class Stats> void check_stat(const Stats& s1, const Stats& s2)
{
BOOST_TEST(exact_same(s1.average, s2.average));
BOOST_TEST(exact_same(s1.variance, s2.variance));
BOOST_TEST(exact_same(s1.deviation, s2.deviation));
BOOST_TEST(esentially_same(s1.average, s2.average));
BOOST_TEST(esentially_same(s1.variance, s2.variance));
BOOST_TEST(esentially_same(s1.deviation, s2.deviation));
}
template <class Stats>
@@ -345,15 +354,28 @@ UNORDERED_AUTO_TEST (stats_) {
boost::concurrent_flat_map<
int, int, boost::hash<int>, std::equal_to<int>,
unequal_allocator< std::pair< const int, int> >>>();
test_stats<
boost::concurrent_node_map<
int, int, boost::hash<int>, std::equal_to<int>,
unequal_allocator< std::pair< const int, int> >>>();
test_stats<
boost::concurrent_flat_set<
int, boost::hash<int>, std::equal_to<int>, unequal_allocator<int>>>();
test_stats<
boost::concurrent_node_set<
int, boost::hash<int>, std::equal_to<int>, unequal_allocator<int>>>();
test_stats_concurrent_unordered_interop<
boost::unordered_flat_map<int, int>,
boost::concurrent_flat_map<int, int>>();
test_stats_concurrent_unordered_interop<
boost::unordered_node_map<int, int>,
boost::concurrent_node_map<int, int>>();
test_stats_concurrent_unordered_interop<
boost::unordered_flat_set<int>,
boost::concurrent_flat_set<int>>();
test_stats_concurrent_unordered_interop<
boost::unordered_node_set<int>,
boost::concurrent_node_set<int>>();
#elif defined(BOOST_UNORDERED_FOA_TESTS)
test_stats<
boost::unordered_flat_map<