Update interim prototype to eschew allocator wrapper and instead use extended map_types

This commit is contained in:
Christian Mazakas
2023-01-03 15:36:25 -08:00
parent a858517c49
commit 1d8d065113
3 changed files with 332 additions and 399 deletions

View File

@ -38,6 +38,8 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
template <class> struct X;
#if defined(__SSE2__)||\ #if defined(__SSE2__)||\
defined(_M_X64)||(defined(_M_IX86_FP)&&_M_IX86_FP>=2) defined(_M_X64)||(defined(_M_IX86_FP)&&_M_IX86_FP>=2)
#define BOOST_UNORDERED_SSE2 #define BOOST_UNORDERED_SSE2
@ -921,7 +923,10 @@ struct table_arrays
template<typename Allocator> template<typename Allocator>
static table_arrays new_(Allocator& al,std::size_t n) static table_arrays new_(Allocator& al,std::size_t n)
{ {
using alloc_traits=boost::allocator_traits<Allocator>; // using alloc_traits=boost::allocator_traits<Allocator>;
using storage_allocator=
typename boost::allocator_rebind<Allocator, Value>::type;
using storage_traits=boost::allocator_traits<storage_allocator>;
auto groups_size_index=size_index_for<group_type,size_policy>(n); auto groups_size_index=size_index_for<group_type,size_policy>(n);
auto groups_size=size_policy::size(groups_size_index); auto groups_size=size_policy::size(groups_size_index);
@ -931,8 +936,9 @@ struct table_arrays
arrays.groups=dummy_groups<group_type,size_policy::min_size()>(); arrays.groups=dummy_groups<group_type,size_policy::min_size()>();
} }
else{ else{
arrays.elements= auto sal=storage_allocator(al);
boost::to_address(alloc_traits::allocate(al,buffer_size(groups_size))); arrays.elements=boost::to_address(
storage_traits::allocate(sal,buffer_size(groups_size)));
/* Align arrays.groups to sizeof(group_type). table_iterator critically /* Align arrays.groups to sizeof(group_type). table_iterator critically
* depends on such alignment for its increment operation. * depends on such alignment for its increment operation.
@ -956,13 +962,15 @@ struct table_arrays
template<typename Allocator> template<typename Allocator>
static void delete_(Allocator& al,table_arrays& arrays)noexcept static void delete_(Allocator& al,table_arrays& arrays)noexcept
{ {
using alloc_traits=boost::allocator_traits<Allocator>; using storage_alloc=typename boost::allocator_rebind<Allocator,Value>::type;
using alloc_traits=boost::allocator_traits<storage_alloc>;
using pointer=typename alloc_traits::pointer; using pointer=typename alloc_traits::pointer;
using pointer_traits=boost::pointer_traits<pointer>; using pointer_traits=boost::pointer_traits<pointer>;
auto sal=storage_alloc(al);
if(arrays.elements){ if(arrays.elements){
alloc_traits::deallocate( alloc_traits::deallocate(
al,pointer_traits::pointer_to(*arrays.elements), sal,pointer_traits::pointer_to(*arrays.elements),
buffer_size(arrays.groups_size_mask+1)); buffer_size(arrays.groups_size_mask+1));
} }
} }
@ -1579,7 +1587,7 @@ private:
template<typename... Args> template<typename... Args>
void construct_element(storage_type* p,Args&&... args) void construct_element(storage_type* p,Args&&... args)
{ {
alloc_traits::construct(al(),p,std::forward<Args>(args)...); type_policy::construct(al(),p,std::forward<Args>(args)...);
} }
template<typename... Args> template<typename... Args>
@ -1595,7 +1603,7 @@ private:
void construct_element_from_try_emplace_args( void construct_element_from_try_emplace_args(
storage_type* p,std::false_type,Key&& x,Args&&... args) storage_type* p,std::false_type,Key&& x,Args&&... args)
{ {
alloc_traits::construct( type_policy::construct(
al(),p, al(),p,
std::piecewise_construct, std::piecewise_construct,
std::forward_as_tuple(std::forward<Key>(x)), std::forward_as_tuple(std::forward<Key>(x)),
@ -1610,12 +1618,12 @@ private:
void construct_element_from_try_emplace_args( void construct_element_from_try_emplace_args(
storage_type* p,std::true_type,Key&& x) storage_type* p,std::true_type,Key&& x)
{ {
alloc_traits::construct(al(),p,std::forward<Key>(x)); type_policy::construct(al(),p,std::forward<Key>(x));
} }
void destroy_element(storage_type* p)noexcept void destroy_element(storage_type* p)noexcept
{ {
alloc_traits::destroy(al(),p); type_policy::destroy(al(),p);
} }
struct destroy_element_on_exit struct destroy_element_on_exit
@ -1962,8 +1970,8 @@ private:
p,hash_for(key_from(*p)),arrays_,num_destroyed, p,hash_for(key_from(*p)),arrays_,num_destroyed,
std::integral_constant< /* std::move_if_noexcept semantics */ std::integral_constant< /* std::move_if_noexcept semantics */
bool, bool,
std::is_nothrow_move_constructible<init_type>::value|| std::is_nothrow_move_constructible<storage_type>::value||
!std::is_copy_constructible<init_type>::value>{}); !std::is_copy_constructible<storage_type>::value>{});
} }
void nosize_transfer_element( void nosize_transfer_element(

View File

@ -33,113 +33,6 @@ namespace boost {
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */ #pragma warning(disable : 4714) /* marked as __forceinline not inlined */
#endif #endif
namespace detail {
template <typename Allocator> class ptr_allocator_adaptor
{
using alloc_traits = std::allocator_traits<Allocator>;
using ptr_allocator = typename alloc_traits::template rebind_alloc<
typename Allocator::value_type*>;
using ptr_alloc_traits = std::allocator_traits<ptr_allocator>;
template <class U> friend class ptr_allocator_adaptor;
Allocator al;
public:
using pointer = typename boost::allocator_pointer<ptr_allocator>::type;
using const_pointer =
typename boost::allocator_const_pointer<ptr_allocator>::type;
using void_pointer =
typename boost::allocator_void_pointer<ptr_allocator>::type;
using const_void_pointer =
typename boost::allocator_const_void_pointer<ptr_allocator>::type;
using value_type = typename Allocator::value_type*;
using size_type =
typename boost::allocator_size_type<ptr_allocator>::type;
using difference_type =
typename boost::allocator_difference_type<ptr_allocator>::type;
template <typename U> struct rebind
{
using other = ptr_allocator_adaptor<
typename alloc_traits::template rebind_alloc<U> >;
};
ptr_allocator_adaptor() = default;
ptr_allocator_adaptor(const Allocator& al_) : al{al_} {}
template <typename Allocator2>
ptr_allocator_adaptor(
const ptr_allocator_adaptor<Allocator2>& x) noexcept : al{x.al}
{
}
template <typename Allocator2>
bool operator==(
const ptr_allocator_adaptor<Allocator2>& x) const noexcept
{
return al == x.al;
}
template <typename Allocator2>
bool operator!=(
const ptr_allocator_adaptor<Allocator2>& x) const noexcept
{
return al != x.al;
}
pointer allocate(std::size_t n)
{
ptr_allocator pal = al;
return ptr_alloc_traits::allocate(pal, n);
}
void deallocate(pointer p, std::size_t n) noexcept
{
ptr_allocator pal = al;
ptr_alloc_traits::deallocate(pal, p, n);
}
void construct(value_type* p, const value_type& x)
{
this->construct(p, *x);
}
void construct(value_type* p, value_type&& x)
{
*p = x;
x = nullptr;
}
template <typename... Args>
void construct(value_type* p, Args&&... args)
{
*p = boost::to_address(alloc_traits::allocate(al, 1));
try {
alloc_traits::construct(al, *p, std::forward<Args>(args)...);
} catch (...) {
alloc_traits::deallocate(al,
boost::pointer_traits<typename alloc_traits::pointer>::pointer_to(
**p),
1);
throw;
}
}
void destroy(value_type* p) noexcept
{
if (*p) {
alloc_traits::destroy(al, *p);
alloc_traits::deallocate(al, *p, 1);
}
}
};
} // namespace detail
template <class Key, class T, class Hash, class KeyEqual, class Allocator> template <class Key, class T, class Hash, class KeyEqual, class Allocator>
class unordered_node_map class unordered_node_map
{ {
@ -169,11 +62,44 @@ namespace boost {
} }
static storage_type&& move(storage_type& x) { return std::move(x); } static storage_type&& move(storage_type& x) { return std::move(x); }
template <class A>
static void construct(A&, storage_type* p, moved_type&& x)
{
*p = x;
x = nullptr;
}
template <class A, class... Args>
static void construct(A& al, storage_type* p, Args&&... args)
{
*p=boost::to_address(boost::allocator_allocate(al, 1));
try {
boost::allocator_construct(al, *p, std::forward<Args>(args)...);
} catch (...) {
boost::allocator_deallocate(al,
boost::pointer_traits<
typename boost::allocator_pointer<A>::type>::pointer_to(**p),
1);
throw;
}
}
template <class A> static void destroy(A& al, storage_type* p) noexcept
{
if (*p) {
boost::allocator_destroy(al, *p);
boost::allocator_deallocate(al,
boost::pointer_traits<
typename boost::allocator_pointer<A>::type>::pointer_to(**p),
1);
}
}
}; };
using table_type = detail::foa::table<map_types, Hash, KeyEqual, using table_type = detail::foa::table<map_types, Hash, KeyEqual,
detail::ptr_allocator_adaptor<typename boost::allocator_rebind< typename boost::allocator_rebind<Allocator,
Allocator, std::pair<Key const, T> >::type> >; std::pair<Key const, T> >::type>;
table_type table_; table_type table_;
@ -207,7 +133,7 @@ namespace boost {
explicit unordered_node_map(size_type n, hasher const& h = hasher(), explicit unordered_node_map(size_type n, hasher const& h = hasher(),
key_equal const& pred = key_equal(), key_equal const& pred = key_equal(),
allocator_type const& a = allocator_type()) allocator_type const& a = allocator_type())
: table_(n, h, pred, detail::ptr_allocator_adaptor<allocator_type>(a)) : table_(n, h, pred, a)
{ {
} }
@ -374,8 +300,7 @@ namespace boost {
BOOST_FORCEINLINE iterator insert(const_iterator, init_type&& value) BOOST_FORCEINLINE iterator insert(const_iterator, init_type&& value)
{ {
return table_ return table_.insert(std::move(value.first), std::move(value.second))
.insert(std::move(value.first), std::move(value.second))
.first; .first;
} }

View File

@ -900,40 +900,40 @@ namespace insert_tests {
test::equal_to, test::allocator2<test::movable> >* test_node_map; test::equal_to, test::allocator2<test::movable> >* test_node_map;
UNORDERED_TEST(unique_insert_tests1, UNORDERED_TEST(unique_insert_tests1,
((test_set_std_alloc)(test_set)(test_map)(test_node_map))( (/* (test_set_std_alloc)(test_set)(test_map) */(test_node_map))(
(default_generator)(generate_collisions)(limited_range))) (default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST( // UNORDERED_TEST(
insert_tests2, ((test_set)(test_map)(test_node_map))( // insert_tests2, ((test_set)(test_map)(test_node_map))(
(default_generator)(generate_collisions)(limited_range))) // (default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(unique_emplace_tests1, // UNORDERED_TEST(unique_emplace_tests1,
((test_set_std_alloc)(test_set)(test_map)(test_node_map))( // ((test_set_std_alloc)(test_set)(test_map)(test_node_map))(
(default_generator)(generate_collisions)(limited_range))) // (default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(move_emplace_tests, // UNORDERED_TEST(move_emplace_tests,
((test_set_std_alloc)(test_set)(test_map)(test_node_map))( // ((test_set_std_alloc)(test_set)(test_map)(test_node_map))(
(default_generator)(generate_collisions)(limited_range))) // (default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(default_emplace_tests, // UNORDERED_TEST(default_emplace_tests,
((test_set_std_alloc)(test_set)(test_map)(test_node_map))( // ((test_set_std_alloc)(test_set)(test_map)(test_node_map))(
(default_generator)(generate_collisions)(limited_range))) // (default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(map_tests, // UNORDERED_TEST(map_tests,
((test_map)(test_node_map)) // ((test_map)(test_node_map))
((default_generator)(generate_collisions)(limited_range))) // ((default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST( // UNORDERED_TEST(
map_tests2, ((test_map)(test_node_map))((default_generator)(generate_collisions))) // map_tests2, ((test_map)(test_node_map))((default_generator)(generate_collisions)))
UNORDERED_TEST(map_insert_range_test1, // UNORDERED_TEST(map_insert_range_test1,
((test_map)(test_node_map))((default_generator)(generate_collisions)(limited_range))) // ((test_map)(test_node_map))((default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(map_insert_range_test2, // UNORDERED_TEST(map_insert_range_test2,
((test_map)(test_node_map))((default_generator)(generate_collisions)(limited_range))) // ((test_map)(test_node_map))((default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST( // UNORDERED_TEST(
set_tests, ((test_set_std_alloc)(test_set))((default_generator))) // set_tests, ((test_set_std_alloc)(test_set))((default_generator)))
#else #else
boost::unordered_set<test::movable, test::hash, test::equal_to, boost::unordered_set<test::movable, test::hash, test::equal_to,
std::allocator<test::movable> >* test_set_std_alloc; std::allocator<test::movable> >* test_set_std_alloc;
@ -995,87 +995,87 @@ namespace insert_tests {
set_tests, ((test_set_std_alloc)(test_set)(test_multiset))((default_generator))) set_tests, ((test_set_std_alloc)(test_set)(test_multiset))((default_generator)))
#endif #endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) // #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
struct initialize_from_two_ints // struct initialize_from_two_ints
{ // {
int a, b; // int a, b;
friend std::size_t hash_value(initialize_from_two_ints const& x) // friend std::size_t hash_value(initialize_from_two_ints const& x)
{ // {
return static_cast<std::size_t>(x.a + x.b); // return static_cast<std::size_t>(x.a + x.b);
} // }
bool operator==(initialize_from_two_ints const& x) const // bool operator==(initialize_from_two_ints const& x) const
{ // {
return a == x.a && b == x.b; // return a == x.a && b == x.b;
} // }
}; // };
UNORDERED_AUTO_TEST (insert_initializer_list_set) { // UNORDERED_AUTO_TEST (insert_initializer_list_set) {
#ifdef BOOST_UNORDERED_FOA_TESTS // #ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set<int> set; // boost::unordered_flat_set<int> set;
#else // #else
boost::unordered_set<int> set; // boost::unordered_set<int> set;
#endif // #endif
set.insert({1, 2, 3, 1}); // set.insert({1, 2, 3, 1});
BOOST_TEST_EQ(set.size(), 3u); // BOOST_TEST_EQ(set.size(), 3u);
BOOST_TEST(set.find(1) != set.end()); // BOOST_TEST(set.find(1) != set.end());
BOOST_TEST(set.find(4) == set.end()); // BOOST_TEST(set.find(4) == set.end());
#ifdef BOOST_UNORDERED_FOA_TESTS // #ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set<initialize_from_two_ints> set2; // boost::unordered_flat_set<initialize_from_two_ints> set2;
#else // #else
boost::unordered_set<initialize_from_two_ints> set2; // boost::unordered_set<initialize_from_two_ints> set2;
#endif // #endif
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)) // #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))
set2.insert({{1, 2}}); // set2.insert({{1, 2}});
#else // #else
set2.insert({1, 2}); // set2.insert({1, 2});
#endif // #endif
BOOST_TEST(set2.size() == 1); // BOOST_TEST(set2.size() == 1);
BOOST_TEST(set2.find({1, 2}) != set2.end()); // BOOST_TEST(set2.find({1, 2}) != set2.end());
BOOST_TEST(set2.find({2, 1}) == set2.end()); // BOOST_TEST(set2.find({2, 1}) == set2.end());
set2.insert({{3, 4}, {5, 6}, {7, 8}}); // set2.insert({{3, 4}, {5, 6}, {7, 8}});
BOOST_TEST(set2.size() == 4); // BOOST_TEST(set2.size() == 4);
BOOST_TEST(set2.find({1, 2}) != set2.end()); // BOOST_TEST(set2.find({1, 2}) != set2.end());
BOOST_TEST(set2.find({3, 4}) != set2.end()); // BOOST_TEST(set2.find({3, 4}) != set2.end());
BOOST_TEST(set2.find({5, 6}) != set2.end()); // BOOST_TEST(set2.find({5, 6}) != set2.end());
BOOST_TEST(set2.find({7, 8}) != set2.end()); // BOOST_TEST(set2.find({7, 8}) != set2.end());
BOOST_TEST(set2.find({8, 7}) == set2.end()); // BOOST_TEST(set2.find({8, 7}) == set2.end());
set2.insert({{2, 1}, {3, 4}}); // set2.insert({{2, 1}, {3, 4}});
BOOST_TEST(set2.size() == 5); // BOOST_TEST(set2.size() == 5);
BOOST_TEST(set2.find({1, 2}) != set2.end()); // BOOST_TEST(set2.find({1, 2}) != set2.end());
BOOST_TEST(set2.find({2, 1}) != set2.end()); // BOOST_TEST(set2.find({2, 1}) != set2.end());
BOOST_TEST(set2.find({3, 4}) != set2.end()); // BOOST_TEST(set2.find({3, 4}) != set2.end());
BOOST_TEST(set2.find({5, 6}) != set2.end()); // BOOST_TEST(set2.find({5, 6}) != set2.end());
BOOST_TEST(set2.find({7, 8}) != set2.end()); // BOOST_TEST(set2.find({7, 8}) != set2.end());
BOOST_TEST(set2.find({8, 7}) == set2.end()); // BOOST_TEST(set2.find({8, 7}) == set2.end());
} // }
#ifndef BOOST_UNORDERED_FOA_TESTS // #ifndef BOOST_UNORDERED_FOA_TESTS
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800) // #if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
UNORDERED_AUTO_TEST (insert_initializer_list_multiset) { // UNORDERED_AUTO_TEST (insert_initializer_list_multiset) {
boost::unordered_multiset<std::string> multiset; // boost::unordered_multiset<std::string> multiset;
// multiset.insert({}); // // multiset.insert({});
BOOST_TEST(multiset.empty()); // BOOST_TEST(multiset.empty());
multiset.insert({"a"}); // multiset.insert({"a"});
BOOST_TEST_EQ(multiset.size(), 1u); // BOOST_TEST_EQ(multiset.size(), 1u);
BOOST_TEST(multiset.find("a") != multiset.end()); // BOOST_TEST(multiset.find("a") != multiset.end());
BOOST_TEST(multiset.find("b") == multiset.end()); // BOOST_TEST(multiset.find("b") == multiset.end());
multiset.insert({"a", "b"}); // multiset.insert({"a", "b"});
BOOST_TEST(multiset.size() == 3); // BOOST_TEST(multiset.size() == 3);
BOOST_TEST_EQ(multiset.count("a"), 2u); // BOOST_TEST_EQ(multiset.count("a"), 2u);
BOOST_TEST_EQ(multiset.count("b"), 1u); // BOOST_TEST_EQ(multiset.count("b"), 1u);
BOOST_TEST_EQ(multiset.count("c"), 0u); // BOOST_TEST_EQ(multiset.count("c"), 0u);
} // }
#endif // #endif
#endif // #endif
template <class Map> static void insert_initializer_list_map_impl() template <class Map> static void insert_initializer_list_map_impl()
{ {
@ -1088,8 +1088,8 @@ namespace insert_tests {
UNORDERED_AUTO_TEST (insert_initializer_list_map) { UNORDERED_AUTO_TEST (insert_initializer_list_map) {
#ifdef BOOST_UNORDERED_FOA_TESTS #ifdef BOOST_UNORDERED_FOA_TESTS
insert_initializer_list_map_impl< // insert_initializer_list_map_impl<
boost::unordered_flat_map<std::string, std::string> >(); // boost::unordered_flat_map<std::string, std::string> >();
insert_initializer_list_map_impl< insert_initializer_list_map_impl<
boost::unordered_node_map<std::string, std::string> >(); boost::unordered_node_map<std::string, std::string> >();
#else #else
@ -1098,18 +1098,18 @@ namespace insert_tests {
#endif #endif
} }
#ifndef BOOST_UNORDERED_FOA_TESTS // #ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (insert_initializer_list_multimap) { // UNORDERED_AUTO_TEST (insert_initializer_list_multimap) {
boost::unordered_multimap<std::string, std::string> multimap; // boost::unordered_multimap<std::string, std::string> multimap;
// multimap.insert({}); // // multimap.insert({});
BOOST_TEST(multimap.empty()); // BOOST_TEST(multimap.empty());
multimap.insert({{"a", "b"}, {"a", "b"}, {"d", ""}}); // multimap.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
BOOST_TEST_EQ(multimap.size(), 3u); // BOOST_TEST_EQ(multimap.size(), 3u);
BOOST_TEST_EQ(multimap.count("a"), 2u); // BOOST_TEST_EQ(multimap.count("a"), 2u);
} // }
#endif // #endif
#endif // #endif
struct overloaded_constructor struct overloaded_constructor
{ {
@ -1157,17 +1157,17 @@ namespace insert_tests {
UNORDERED_AUTO_TEST (map_emplace_test) { UNORDERED_AUTO_TEST (map_emplace_test) {
{ {
#ifdef BOOST_UNORDERED_FOA_TESTS #ifdef BOOST_UNORDERED_FOA_TESTS
typedef boost::unordered_flat_map<int, overloaded_constructor, test::hash, // typedef boost::unordered_flat_map<int, overloaded_constructor, test::hash,
test::equal_to, // test::equal_to,
test::allocator1<std::pair<int const, overloaded_constructor> > > // test::allocator1<std::pair<int const, overloaded_constructor> > >
flat_map; // flat_map;
typedef boost::unordered_node_map<int, overloaded_constructor, test::hash, typedef boost::unordered_node_map<int, overloaded_constructor, test::hash,
test::equal_to, test::equal_to,
test::allocator1<std::pair<int const, overloaded_constructor> > > test::allocator1<std::pair<int const, overloaded_constructor> > >
node_map; node_map;
map_emplace_test_impl<flat_map>(); // map_emplace_test_impl<flat_map>();
map_emplace_test_impl<node_map>(); map_emplace_test_impl<node_map>();
#else #else
typedef boost::unordered_map<int, overloaded_constructor, test::hash, typedef boost::unordered_map<int, overloaded_constructor, test::hash,
@ -1199,40 +1199,40 @@ namespace insert_tests {
#endif #endif
} }
UNORDERED_AUTO_TEST (set_emplace_test) { // UNORDERED_AUTO_TEST (set_emplace_test) {
#ifdef BOOST_UNORDERED_FOA_TESTS // #ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set<overloaded_constructor> x; // boost::unordered_flat_set<overloaded_constructor> x;
overloaded_constructor check; // overloaded_constructor check;
#else // #else
boost::unordered_set<overloaded_constructor> x; // boost::unordered_set<overloaded_constructor> x;
overloaded_constructor check; // overloaded_constructor check;
#endif // #endif
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1 // #if !BOOST_UNORDERED_SUN_WORKAROUNDS1
x.emplace(); // x.emplace();
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
#endif // #endif
x.clear(); // x.clear();
x.emplace(1); // x.emplace(1);
check = overloaded_constructor(1); // check = overloaded_constructor(1);
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
x.clear(); // x.clear();
x.emplace(2, 3); // x.emplace(2, 3);
check = overloaded_constructor(2, 3); // check = overloaded_constructor(2, 3);
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
x.clear(); // x.clear();
x.emplace(4, 5, 6); // x.emplace(4, 5, 6);
check = overloaded_constructor(4, 5, 6); // check = overloaded_constructor(4, 5, 6);
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
x.clear(); // x.clear();
x.emplace(7, 8, 9, 10); // x.emplace(7, 8, 9, 10);
check = overloaded_constructor(7, 8, 9, 10); // check = overloaded_constructor(7, 8, 9, 10);
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
} // }
struct derived_from_piecewise_construct_t struct derived_from_piecewise_construct_t
: boost::unordered::piecewise_construct_t : boost::unordered::piecewise_construct_t
@ -1252,131 +1252,131 @@ namespace insert_tests {
} }
}; };
#ifndef BOOST_UNORDERED_FOA_TESTS // #ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (map_emplace_test2) { // UNORDERED_AUTO_TEST (map_emplace_test2) {
// Emulating piecewise construction with boost::tuple bypasses the // // Emulating piecewise construction with boost::tuple bypasses the
// allocator's construct method, but still uses test destroy method. // // allocator's construct method, but still uses test destroy method.
test::detail::disable_construction_tracking _scoped; // test::detail::disable_construction_tracking _scoped;
{ // {
boost::unordered_map<overloaded_constructor, overloaded_constructor, // boost::unordered_map<overloaded_constructor, overloaded_constructor,
boost::hash<overloaded_constructor>, // boost::hash<overloaded_constructor>,
std::equal_to<overloaded_constructor>, // std::equal_to<overloaded_constructor>,
test::allocator1< // test::allocator1<
std::pair<overloaded_constructor const, overloaded_constructor> > > // std::pair<overloaded_constructor const, overloaded_constructor> > >
x; // x;
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), // x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
boost::make_tuple()); // boost::make_tuple());
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor()) != x.end() && // x.find(overloaded_constructor()) != x.end() &&
x.find(overloaded_constructor())->second == overloaded_constructor()); // x.find(overloaded_constructor())->second == overloaded_constructor());
x.emplace( // x.emplace(
convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple()); // convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple());
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor(1)) != x.end() && // x.find(overloaded_constructor(1)) != x.end() &&
x.find(overloaded_constructor(1))->second == overloaded_constructor()); // x.find(overloaded_constructor(1))->second == overloaded_constructor());
x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3), // x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3),
boost::make_tuple(4, 5, 6)); // boost::make_tuple(4, 5, 6));
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && // BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
x.find(overloaded_constructor(2, 3))->second == // x.find(overloaded_constructor(2, 3))->second ==
overloaded_constructor(4, 5, 6)); // overloaded_constructor(4, 5, 6));
derived_from_piecewise_construct_t d; // derived_from_piecewise_construct_t d;
x.emplace(d, boost::make_tuple(9, 3, 1), boost::make_tuple(10)); // x.emplace(d, boost::make_tuple(9, 3, 1), boost::make_tuple(10));
BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() && // BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() &&
x.find(overloaded_constructor(9, 3, 1))->second == // x.find(overloaded_constructor(9, 3, 1))->second ==
overloaded_constructor(10)); // overloaded_constructor(10));
x.clear(); // x.clear();
x.try_emplace(overloaded_constructor()); // x.try_emplace(overloaded_constructor());
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor()) != x.end() && // x.find(overloaded_constructor()) != x.end() &&
x.find(overloaded_constructor())->second == overloaded_constructor()); // x.find(overloaded_constructor())->second == overloaded_constructor());
x.try_emplace(1); // x.try_emplace(1);
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor(1)) != x.end() && // x.find(overloaded_constructor(1)) != x.end() &&
x.find(overloaded_constructor(1))->second == overloaded_constructor()); // x.find(overloaded_constructor(1))->second == overloaded_constructor());
x.try_emplace(overloaded_constructor(2, 3), 4, 5, 6); // x.try_emplace(overloaded_constructor(2, 3), 4, 5, 6);
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && // BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
x.find(overloaded_constructor(2, 3))->second == // x.find(overloaded_constructor(2, 3))->second ==
overloaded_constructor(4, 5, 6)); // overloaded_constructor(4, 5, 6));
x.clear(); // x.clear();
x.try_emplace(x.begin(), overloaded_constructor()); // x.try_emplace(x.begin(), overloaded_constructor());
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor()) != x.end() && // x.find(overloaded_constructor()) != x.end() &&
x.find(overloaded_constructor())->second == overloaded_constructor()); // x.find(overloaded_constructor())->second == overloaded_constructor());
x.try_emplace(x.end(), 1); // x.try_emplace(x.end(), 1);
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor(1)) != x.end() && // x.find(overloaded_constructor(1)) != x.end() &&
x.find(overloaded_constructor(1))->second == overloaded_constructor()); // x.find(overloaded_constructor(1))->second == overloaded_constructor());
x.try_emplace(x.begin(), overloaded_constructor(2, 3), 4, 5, 6); // x.try_emplace(x.begin(), overloaded_constructor(2, 3), 4, 5, 6);
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && // BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
x.find(overloaded_constructor(2, 3))->second == // x.find(overloaded_constructor(2, 3))->second ==
overloaded_constructor(4, 5, 6)); // overloaded_constructor(4, 5, 6));
} // }
{ // {
boost::unordered_multimap<overloaded_constructor, overloaded_constructor, // boost::unordered_multimap<overloaded_constructor, overloaded_constructor,
boost::hash<overloaded_constructor>, // boost::hash<overloaded_constructor>,
std::equal_to<overloaded_constructor>, // std::equal_to<overloaded_constructor>,
test::allocator1< // test::allocator1<
std::pair<overloaded_constructor const, overloaded_constructor> > > // std::pair<overloaded_constructor const, overloaded_constructor> > >
x; // x;
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), // x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
boost::make_tuple()); // boost::make_tuple());
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor()) != x.end() && // x.find(overloaded_constructor()) != x.end() &&
x.find(overloaded_constructor())->second == overloaded_constructor()); // x.find(overloaded_constructor())->second == overloaded_constructor());
x.emplace( // x.emplace(
convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple()); // convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple());
BOOST_TEST( // BOOST_TEST(
x.find(overloaded_constructor(1)) != x.end() && // x.find(overloaded_constructor(1)) != x.end() &&
x.find(overloaded_constructor(1))->second == overloaded_constructor()); // x.find(overloaded_constructor(1))->second == overloaded_constructor());
x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3), // x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3),
boost::make_tuple(4, 5, 6)); // boost::make_tuple(4, 5, 6));
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() && // BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
x.find(overloaded_constructor(2, 3))->second == // x.find(overloaded_constructor(2, 3))->second ==
overloaded_constructor(4, 5, 6)); // overloaded_constructor(4, 5, 6));
derived_from_piecewise_construct_t d; // derived_from_piecewise_construct_t d;
x.emplace(d, boost::make_tuple(9, 3, 1), boost::make_tuple(10)); // x.emplace(d, boost::make_tuple(9, 3, 1), boost::make_tuple(10));
BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() && // BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() &&
x.find(overloaded_constructor(9, 3, 1))->second == // x.find(overloaded_constructor(9, 3, 1))->second ==
overloaded_constructor(10)); // overloaded_constructor(10));
} // }
} // }
UNORDERED_AUTO_TEST (set_emplace_test2) { // UNORDERED_AUTO_TEST (set_emplace_test2) {
boost::unordered_set< // boost::unordered_set<
std::pair<overloaded_constructor, overloaded_constructor> > // std::pair<overloaded_constructor, overloaded_constructor> >
x; // x;
std::pair<overloaded_constructor, overloaded_constructor> check; // std::pair<overloaded_constructor, overloaded_constructor> check;
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), // x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
boost::make_tuple()); // boost::make_tuple());
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
x.clear(); // x.clear();
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1), // x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1),
boost::make_tuple(2, 3)); // boost::make_tuple(2, 3));
check = // check =
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3)); // std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
} // }
#endif // #endif
// Use the preprocessor to generate tests using different combinations of // Use the preprocessor to generate tests using different combinations of
// boost/std piecewise_construct_t/tuple. // boost/std piecewise_construct_t/tuple.
@ -1486,12 +1486,12 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
{ {
#if defined(BOOST_UNORDERED_FOA_TESTS) #if defined(BOOST_UNORDERED_FOA_TESTS)
typedef boost::unordered_flat_map<overloaded_constructor, overloaded_constructor, // typedef boost::unordered_flat_map<overloaded_constructor, overloaded_constructor,
boost::hash<overloaded_constructor>, // boost::hash<overloaded_constructor>,
std::equal_to<overloaded_constructor>, // std::equal_to<overloaded_constructor>,
test::allocator1< // test::allocator1<
std::pair<overloaded_constructor const, overloaded_constructor> > > // std::pair<overloaded_constructor const, overloaded_constructor> > >
flat_map; // flat_map;
typedef boost::unordered_node_map<overloaded_constructor, overloaded_constructor, typedef boost::unordered_node_map<overloaded_constructor, overloaded_constructor,
boost::hash<overloaded_constructor>, boost::hash<overloaded_constructor>,
@ -1500,7 +1500,7 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
std::pair<overloaded_constructor const, overloaded_constructor> > > std::pair<overloaded_constructor const, overloaded_constructor> > >
node_map; node_map;
piecewise_test_impl<flat_map>(); // piecewise_test_impl<flat_map>();
piecewise_test_impl<node_map>(); piecewise_test_impl<node_map>();
#else #else
typedef boost::unordered_map<overloaded_constructor, overloaded_constructor, typedef boost::unordered_map<overloaded_constructor, overloaded_constructor,
@ -1550,33 +1550,33 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
#endif #endif
} }
UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) { // UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
#if EMULATING_PIECEWISE_CONSTRUCTION // #if EMULATING_PIECEWISE_CONSTRUCTION
test::detail::disable_construction_tracking _scoped; // test::detail::disable_construction_tracking _scoped;
#endif // #endif
#ifdef BOOST_UNORDERED_FOA_TESTS // #ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set< // boost::unordered_flat_set<
std::pair<overloaded_constructor, overloaded_constructor> > // std::pair<overloaded_constructor, overloaded_constructor> >
x; // x;
#else // #else
boost::unordered_set< // boost::unordered_set<
std::pair<overloaded_constructor, overloaded_constructor> > // std::pair<overloaded_constructor, overloaded_constructor> >
x; // x;
#endif // #endif
std::pair<overloaded_constructor, overloaded_constructor> check; // std::pair<overloaded_constructor, overloaded_constructor> check;
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct, // x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple()); // TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple());
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
x.clear(); // x.clear();
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct, // x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
TUPLE_NAMESPACE::make_tuple(1), TUPLE_NAMESPACE::make_tuple(2, 3)); // TUPLE_NAMESPACE::make_tuple(1), TUPLE_NAMESPACE::make_tuple(2, 3));
check = // check =
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3)); // std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); // BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
} // }
#undef PIECEWISE_TEST_NAME #undef PIECEWISE_TEST_NAME
#undef PIECEWISE_NAMESPACE #undef PIECEWISE_NAMESPACE