mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
Split move_tests into post_move_tests so testing with the new FOA containers is feasible
This commit is contained in:
@ -47,6 +47,7 @@ run unordered/equivalent_keys_tests.cpp ;
|
||||
run unordered/constructor_tests.cpp ;
|
||||
run unordered/copy_tests.cpp ;
|
||||
run unordered/move_tests.cpp ;
|
||||
run unordered/post_move_tests.cpp ;
|
||||
run unordered/assign_tests.cpp ;
|
||||
run unordered/insert_tests.cpp ;
|
||||
run unordered/insert_stable_tests.cpp ;
|
||||
|
@ -344,519 +344,6 @@ namespace move_tests {
|
||||
}
|
||||
}
|
||||
|
||||
template <class T> T const& get_key(T const& t) { return t; }
|
||||
|
||||
template <class K, class V> K const& get_key(std::pair<K const, V> const& kv)
|
||||
{
|
||||
return kv.first;
|
||||
}
|
||||
|
||||
template <class T> T const& get_value(T const& t) { return t; }
|
||||
|
||||
template <class K, class V> K const& get_value(std::pair<K const, V> const& kv)
|
||||
{
|
||||
return kv.second;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_range(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(v.begin(), v.end());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_single(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(*v.begin());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_single_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(y.end(), *v.begin());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> struct insert_or_assign_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct insert_or_assign_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
|
||||
y.insert_or_assign(get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void insert_or_assign(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
insert_or_assign_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct insert_or_assign_hint_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct insert_or_assign_hint_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.insert_or_assign(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void insert_or_assign_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
insert_or_assign_hint_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct try_emplace_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct try_emplace_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.try_emplace(get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void try_emplace(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
try_emplace_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct try_emplace_hint_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct try_emplace_hint_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.try_emplace(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void try_emplace_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
try_emplace_hint_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct at_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct at_invoker<boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
BOOST_TRY { y.at(get_key(*v.begin())); }
|
||||
BOOST_CATCH(...) {}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> static void at(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
at_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct index_operator_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct index_operator_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y[get_key(*v.begin())] = get_value(*v.begin());
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void index_operator(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
index_operator_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> static void clear(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.clear();
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void capacity(T& y, test::random_values<T> const&)
|
||||
{
|
||||
(void)y.empty();
|
||||
(void)y.size();
|
||||
(void)y.max_size();
|
||||
(void)y.load_factor();
|
||||
(void)y.max_load_factor();
|
||||
(void)y.hash_function();
|
||||
(void)y.key_eq();
|
||||
(void)y.get_allocator();
|
||||
}
|
||||
|
||||
template <class T> static void iterators(T& y, test::random_values<T> const&)
|
||||
{
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void erase_range(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.erase(y.begin(), y.end());
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void erase_key(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.erase(get_key(*v.begin()));
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void lookup(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.count(get_key(*v.begin()));
|
||||
(void)y.find(get_key(*v.begin()));
|
||||
(void)y.contains(get_key(*v.begin()));
|
||||
(void)y.equal_range(get_key(*v.begin()));
|
||||
}
|
||||
|
||||
template <class T> static void reserve(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.reserve(1337);
|
||||
BOOST_TEST_GT(y.bucket_count(), 1337u);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void copy_assignment(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
y = x;
|
||||
BOOST_TEST_EQ(y.size(), x.size());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void move_assignment(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
std::size_t const size = x.size();
|
||||
y = boost::move(x);
|
||||
BOOST_TEST_GE(y.size(), size);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void equal(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
(void)(y == x);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void extract(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.extract(get_key(*v.begin()));
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void merge(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
if (y.get_allocator() == x.get_allocator()) {
|
||||
y.merge(x);
|
||||
}
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class X> bool pred(X const&) { return true; }
|
||||
|
||||
template <class T>
|
||||
static void erase_with_pred(T& y, test::random_values<T> const&)
|
||||
{
|
||||
erase_if(y, pred<typename T::value_type>);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void container_swap(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
if (boost::allocator_propagate_on_container_swap<
|
||||
typename T::allocator_type>::type::value ||
|
||||
x.get_allocator() == y.get_allocator()) {
|
||||
y.swap(x);
|
||||
}
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void buckets(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.begin(0);
|
||||
(void)y.end(0);
|
||||
(void)y.bucket_count();
|
||||
(void)y.max_bucket_count();
|
||||
(void)y.bucket_size(0);
|
||||
(void)y.bucket(get_key(*v.begin()));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void double_move_construct(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x = boost::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
BOOST_TEST_EQ(x.size(),
|
||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void double_move_assign(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x;
|
||||
x = boost::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
BOOST_TEST_EQ(x.size(),
|
||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void post_move_tests(T* ptr, test::random_generator const& generator)
|
||||
{
|
||||
// clang-format off
|
||||
void (*fps[])(T&, test::random_values<T> const&) = {
|
||||
insert_range<T>,
|
||||
insert_single<T>,
|
||||
insert_single_hint<T>,
|
||||
insert_or_assign<T>,
|
||||
insert_or_assign_hint<T>,
|
||||
try_emplace<T>,
|
||||
try_emplace_hint<T>,
|
||||
at<T>,
|
||||
index_operator<T>,
|
||||
clear<T>,
|
||||
capacity<T>,
|
||||
iterators<T>,
|
||||
erase_range<T>,
|
||||
erase_key<T>,
|
||||
lookup<T>,
|
||||
reserve<T>,
|
||||
copy_assignment<T>,
|
||||
move_assignment<T>,
|
||||
equal<T>,
|
||||
extract<T>,
|
||||
merge<T>,
|
||||
erase_with_pred<T>,
|
||||
container_swap<T>,
|
||||
buckets<T>,
|
||||
double_move_construct<T>,
|
||||
double_move_assign<T>
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
std::size_t const len = (sizeof(fps) / sizeof(*(fps)));
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> const v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(boost::move(y));
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
typename T::hasher hf(1);
|
||||
typename T::key_equal eq(1);
|
||||
typename T::allocator_type al1(1);
|
||||
typename T::allocator_type al2(2);
|
||||
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
T x(boost::move(y), al2);
|
||||
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(empty(ptr));
|
||||
x = boost::move(y);
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
typename T::hasher hf(1);
|
||||
typename T::key_equal eq(1);
|
||||
typename T::allocator_type al1(1);
|
||||
typename T::allocator_type al2(2);
|
||||
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(al2);
|
||||
x = boost::move(y);
|
||||
|
||||
bool b = boost::allocator_propagate_on_container_move_assignment<
|
||||
typename T::allocator_type>::type::value;
|
||||
if (b) {
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#else
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
|
||||
#endif
|
||||
} else {
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
}
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<std::pair<test::object const, test::object> > >*
|
||||
test_map_std_alloc;
|
||||
@ -930,12 +417,6 @@ namespace move_tests {
|
||||
test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(
|
||||
test_multimap_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(post_move_tests,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_move)(
|
||||
test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)(
|
||||
test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(
|
||||
test_multimap_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
627
test/unordered/post_move_tests.cpp
Normal file
627
test/unordered/post_move_tests.cpp
Normal file
@ -0,0 +1,627 @@
|
||||
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
#include "../objects/cxx11_allocator.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
#include "../helpers/equivalent.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace move_tests {
|
||||
test::seed_t initialize_seed(98624);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#define BOOST_UNORDERED_TEST_MOVING 1
|
||||
#else
|
||||
#define BOOST_UNORDERED_TEST_MOVING 0
|
||||
#endif
|
||||
|
||||
template <class T> T empty(T*) { return T(); }
|
||||
|
||||
template <class T>
|
||||
T create(test::random_values<T> const& v, test::object_count& count)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T create(test::random_values<T> const& v, test::object_count& count,
|
||||
typename T::hasher hf, typename T::key_equal eq,
|
||||
typename T::allocator_type al, float mlf)
|
||||
{
|
||||
T x(0, hf, eq, al);
|
||||
x.max_load_factor(mlf);
|
||||
x.insert(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T> T const& get_key(T const& t) { return t; }
|
||||
|
||||
template <class K, class V> K const& get_key(std::pair<K const, V> const& kv)
|
||||
{
|
||||
return kv.first;
|
||||
}
|
||||
|
||||
template <class T> T const& get_value(T const& t) { return t; }
|
||||
|
||||
template <class K, class V> K const& get_value(std::pair<K const, V> const& kv)
|
||||
{
|
||||
return kv.second;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_range(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(v.begin(), v.end());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_single(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(*v.begin());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void insert_single_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.insert(y.end(), *v.begin());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> struct insert_or_assign_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct insert_or_assign_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
|
||||
y.insert_or_assign(get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void insert_or_assign(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
insert_or_assign_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct insert_or_assign_hint_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct insert_or_assign_hint_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.insert_or_assign(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void insert_or_assign_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
insert_or_assign_hint_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct try_emplace_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct try_emplace_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.try_emplace(get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void try_emplace(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
try_emplace_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct try_emplace_hint_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct try_emplace_hint_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y.try_emplace(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void try_emplace_hint(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
try_emplace_hint_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct at_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct at_invoker<boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
BOOST_TRY { y.at(get_key(*v.begin())); }
|
||||
BOOST_CATCH(...) {}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> static void at(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
at_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> struct index_operator_invoker
|
||||
{
|
||||
void operator()(T&, test::random_values<T> const&) {}
|
||||
};
|
||||
|
||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||
struct index_operator_invoker<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||
{
|
||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||
test::random_values<
|
||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||
{
|
||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||
Allocator>::size_type size_type;
|
||||
y[get_key(*v.begin())] = get_value(*v.begin());
|
||||
BOOST_TEST_EQ(
|
||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static void index_operator(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
index_operator_invoker<T>()(y, v);
|
||||
}
|
||||
|
||||
template <class T> static void clear(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.clear();
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void capacity(T& y, test::random_values<T> const&)
|
||||
{
|
||||
(void)y.empty();
|
||||
(void)y.size();
|
||||
(void)y.max_size();
|
||||
(void)y.load_factor();
|
||||
(void)y.max_load_factor();
|
||||
(void)y.hash_function();
|
||||
(void)y.key_eq();
|
||||
(void)y.get_allocator();
|
||||
}
|
||||
|
||||
template <class T> static void iterators(T& y, test::random_values<T> const&)
|
||||
{
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void erase_range(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.erase(y.begin(), y.end());
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void erase_key(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
y.erase(get_key(*v.begin()));
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void lookup(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.count(get_key(*v.begin()));
|
||||
(void)y.find(get_key(*v.begin()));
|
||||
(void)y.contains(get_key(*v.begin()));
|
||||
(void)y.equal_range(get_key(*v.begin()));
|
||||
}
|
||||
|
||||
template <class T> static void reserve(T& y, test::random_values<T> const&)
|
||||
{
|
||||
y.reserve(1337);
|
||||
BOOST_TEST_GT(y.bucket_count(), 1337u);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void copy_assignment(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
y = x;
|
||||
BOOST_TEST_EQ(y.size(), x.size());
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void move_assignment(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
std::size_t const size = x.size();
|
||||
y = boost::move(x);
|
||||
BOOST_TEST_GE(y.size(), size);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void equal(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
(void)(y == x);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void extract(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.extract(get_key(*v.begin()));
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void merge(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
if (y.get_allocator() == x.get_allocator()) {
|
||||
y.merge(x);
|
||||
}
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class X> bool pred(X const&) { return true; }
|
||||
|
||||
template <class T>
|
||||
static void erase_with_pred(T& y, test::random_values<T> const&)
|
||||
{
|
||||
erase_if(y, pred<typename T::value_type>);
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void container_swap(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
if (boost::allocator_propagate_on_container_swap<
|
||||
typename T::allocator_type>::type::value ||
|
||||
x.get_allocator() == y.get_allocator()) {
|
||||
y.swap(x);
|
||||
}
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
}
|
||||
|
||||
template <class T> static void buckets(T& y, test::random_values<T> const& v)
|
||||
{
|
||||
(void)y.begin(0);
|
||||
(void)y.end(0);
|
||||
(void)y.bucket_count();
|
||||
(void)y.max_bucket_count();
|
||||
(void)y.bucket_size(0);
|
||||
(void)y.bucket(get_key(*v.begin()));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void double_move_construct(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x = boost::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
BOOST_TEST_EQ(x.size(),
|
||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void double_move_assign(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x;
|
||||
x = boost::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
BOOST_TEST_EQ(x.size(),
|
||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void post_move_tests(T* ptr, test::random_generator const& generator)
|
||||
{
|
||||
// clang-format off
|
||||
void (*fps[])(T&, test::random_values<T> const&) = {
|
||||
insert_range<T>,
|
||||
insert_single<T>,
|
||||
insert_single_hint<T>,
|
||||
insert_or_assign<T>,
|
||||
insert_or_assign_hint<T>,
|
||||
try_emplace<T>,
|
||||
try_emplace_hint<T>,
|
||||
at<T>,
|
||||
index_operator<T>,
|
||||
clear<T>,
|
||||
capacity<T>,
|
||||
iterators<T>,
|
||||
erase_range<T>,
|
||||
erase_key<T>,
|
||||
lookup<T>,
|
||||
reserve<T>,
|
||||
copy_assignment<T>,
|
||||
move_assignment<T>,
|
||||
equal<T>,
|
||||
extract<T>,
|
||||
merge<T>,
|
||||
erase_with_pred<T>,
|
||||
container_swap<T>,
|
||||
buckets<T>,
|
||||
double_move_construct<T>,
|
||||
double_move_assign<T>
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
std::size_t const len = (sizeof(fps) / sizeof(*(fps)));
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> const v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(boost::move(y));
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
typename T::hasher hf(1);
|
||||
typename T::key_equal eq(1);
|
||||
typename T::allocator_type al1(1);
|
||||
typename T::allocator_type al2(2);
|
||||
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
T x(boost::move(y), al2);
|
||||
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(empty(ptr));
|
||||
x = boost::move(y);
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
typename T::hasher hf(1);
|
||||
typename T::key_equal eq(1);
|
||||
typename T::allocator_type al1(1);
|
||||
typename T::allocator_type al2(2);
|
||||
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(al2);
|
||||
x = boost::move(y);
|
||||
|
||||
bool b = boost::allocator_propagate_on_container_move_assignment<
|
||||
typename T::allocator_type>::type::value;
|
||||
if (b) {
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#else
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
|
||||
#endif
|
||||
} else {
|
||||
BOOST_TEST_NOT(y.empty());
|
||||
BOOST_TEST(y.begin() != y.end());
|
||||
}
|
||||
|
||||
fps[i](y, v);
|
||||
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<std::pair<test::object const, test::object> > >*
|
||||
test_map_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::allocator2<std::pair<test::object const, test::object> > >*
|
||||
test_multimap;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_set_prop_move;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_multiset_prop_move;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_map_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::propagate_move> >* test_multimap_prop_move;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_set_no_prop_move;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_multiset_no_prop_move;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_map_no_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||
test::no_propagate_move> >* test_multimap_no_prop_move;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(post_move_tests,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_move)(
|
||||
test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)(
|
||||
test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(
|
||||
test_multimap_no_prop_move))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
Reference in New Issue
Block a user