Files
boost_unordered/test/unordered/compile_tests.hpp
Daniel James f72b0353d4 Shuffle code around for readability
The new indentation made some of the code difficult to read, especially
where macros were concerned, so move things around and add more explicit
namespace declarations.
2017-06-11 20:55:59 +01:00

841 lines
26 KiB
C++

// Copyright 2005-2009 Daniel James.
// 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)
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable : 4610) // class can never be instantiated
#pragma warning(disable : 4510) // default constructor could not be generated
#endif
#include <boost/concept_check.hpp>
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#include "../helpers/check_return_type.hpp"
#include <boost/iterator/iterator_traits.hpp>
#include <boost/limits.hpp>
#include <boost/predef.h>
#include <boost/static_assert.hpp>
#include <boost/type_traits/cv_traits.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/swap.hpp>
typedef long double comparison_type;
template <class T> void sink(T const&) {}
template <class T> T rvalue(T const& v) { return v; }
template <class T> T rvalue_default() { return T(); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template <class T> T implicit_construct() { return {}; }
#else
template <class T> int implicit_construct()
{
T x;
sink(x);
return 0;
}
#endif
#if !defined(BOOST_NO_CXX11_NOEXCEPT)
#define TEST_NOEXCEPT_EXPR(x) BOOST_STATIC_ASSERT((BOOST_NOEXCEPT_EXPR(x)));
#else
#define TEST_NOEXCEPT_EXPR(x)
#endif
template <class X, class T> void container_test(X& r, T const&)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::difference_type difference_type;
typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<iterator>::type
iterator_value_type;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<const_iterator>::type
const_iterator_value_type;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type
iterator_difference_type;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
const_iterator>::type const_iterator_difference_type;
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME X::reference reference;
typedef BOOST_DEDUCED_TYPENAME X::const_reference const_reference;
typedef BOOST_DEDUCED_TYPENAME X::node_type node_type;
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
// value_type
BOOST_STATIC_ASSERT((boost::is_same<T, value_type>::value));
boost::function_requires<boost::CopyConstructibleConcept<X> >();
// reference_type / const_reference_type
BOOST_STATIC_ASSERT((boost::is_same<T&, reference>::value));
BOOST_STATIC_ASSERT((boost::is_same<T const&, const_reference>::value));
// iterator
boost::function_requires<boost::InputIteratorConcept<iterator> >();
BOOST_STATIC_ASSERT((boost::is_same<T, iterator_value_type>::value));
BOOST_STATIC_ASSERT((boost::is_convertible<iterator, const_iterator>::value));
// const_iterator
boost::function_requires<boost::InputIteratorConcept<const_iterator> >();
BOOST_STATIC_ASSERT((boost::is_same<T, const_iterator_value_type>::value));
// node_type
BOOST_STATIC_ASSERT((boost::is_same<allocator_type,
BOOST_DEDUCED_TYPENAME node_type::allocator_type>::value));
// difference_type
BOOST_STATIC_ASSERT(std::numeric_limits<difference_type>::is_signed);
BOOST_STATIC_ASSERT(std::numeric_limits<difference_type>::is_integer);
BOOST_STATIC_ASSERT(
(boost::is_same<difference_type, iterator_difference_type>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<difference_type, const_iterator_difference_type>::value));
// size_type
BOOST_STATIC_ASSERT(!std::numeric_limits<size_type>::is_signed);
BOOST_STATIC_ASSERT(std::numeric_limits<size_type>::is_integer);
// size_type can represent any non-negative value type of difference_type
// I'm not sure about either of these tests...
size_type max_diff =
static_cast<size_type>((std::numeric_limits<difference_type>::max)());
difference_type converted_diff(static_cast<difference_type>(max_diff));
BOOST_TEST((std::numeric_limits<difference_type>::max)() == converted_diff);
BOOST_TEST(
static_cast<comparison_type>((std::numeric_limits<size_type>::max)()) >
static_cast<comparison_type>(
(std::numeric_limits<difference_type>::max)()));
// Constructors
// I don't test the runtime post-conditions here.
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
// It isn't specified in the container requirements that the no argument
// constructor is implicit, but it is defined that way in the concrete
// container specification.
X u_implicit = {};
sink(u_implicit);
#endif
X u;
BOOST_TEST(u.size() == 0);
BOOST_TEST(X().size() == 0);
X a, b;
X a_const;
sink(X(a));
X u2(a);
X u3 = a;
X u4(rvalue(a_const));
X u5 = rvalue(a_const);
a.swap(b);
boost::swap(a, b);
test::check_return_type<X>::equals_ref(r = a);
// Allocator
test::check_return_type<allocator_type>::equals(a_const.get_allocator());
allocator_type m = a.get_allocator();
sink(X(m));
X c(m);
sink(X(a_const, m));
X c2(a_const, m);
sink(X(rvalue(a_const), m));
X c3(rvalue(a_const), m);
// node_type
implicit_construct<node_type const>();
#if !BOOST_COMP_GNUC || BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4, 8, 0)
TEST_NOEXCEPT_EXPR(node_type());
#endif
node_type n1;
node_type n2(rvalue_default<node_type>());
#if !BOOST_COMP_GNUC || BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4, 8, 0)
TEST_NOEXCEPT_EXPR(node_type(boost::move(n1)));
#endif
node_type n3;
n3 = boost::move(n2);
n1.swap(n3);
swap(n1, n3);
// TODO: noexcept for swap?
// value, key, mapped tests in map and set specific testing.
node_type const n_const;
BOOST_TEST(n_const ? 0 : 1);
TEST_NOEXCEPT_EXPR(n_const ? 0 : 1);
test::check_return_type<bool>::equals(!n_const);
test::check_return_type<bool>::equals(n_const.empty());
TEST_NOEXCEPT_EXPR(!n_const);
TEST_NOEXCEPT_EXPR(n_const.empty());
// Avoid unused variable warnings:
sink(u);
sink(u2);
sink(u3);
sink(u4);
sink(u5);
sink(c);
sink(c2);
sink(c3);
}
template <class X> void unordered_destructible_test(X&)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
X x1;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
X x2(rvalue_default<X>());
X x3 = rvalue_default<X>();
// This can only be done if propagate_on_container_move_assignment::value
// is true.
// x2 = rvalue_default<X>();
#endif
X* ptr = new X();
X& a1 = *ptr;
(&a1)->~X();
::operator delete((void*)(&a1));
X a, b;
X const a_const;
test::check_return_type<iterator>::equals(a.begin());
test::check_return_type<const_iterator>::equals(a_const.begin());
test::check_return_type<const_iterator>::equals(a.cbegin());
test::check_return_type<const_iterator>::equals(a_const.cbegin());
test::check_return_type<iterator>::equals(a.end());
test::check_return_type<const_iterator>::equals(a_const.end());
test::check_return_type<const_iterator>::equals(a.cend());
test::check_return_type<const_iterator>::equals(a_const.cend());
a.swap(b);
boost::swap(a, b);
test::check_return_type<size_type>::equals(a.size());
test::check_return_type<size_type>::equals(a.max_size());
test::check_return_type<bool>::convertible(a.empty());
// Allocator
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
test::check_return_type<allocator_type>::equals(a_const.get_allocator());
}
template <class X, class Key> void unordered_set_test(X& r, Key const&)
{
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
BOOST_STATIC_ASSERT((boost::is_same<value_type, key_type>::value));
// iterator pointer / const_pointer_type
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
const_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
const_local_iterator>::type const_local_iterator_pointer;
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, const_iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, local_iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
typedef BOOST_DEDUCED_TYPENAME X::node_type node_type;
typedef BOOST_DEDUCED_TYPENAME node_type::value_type node_value_type;
BOOST_STATIC_ASSERT((boost::is_same<value_type, node_value_type>::value));
// Call node_type functions.
test::minimal::constructor_param v;
Key k_lvalue(v);
r.emplace(boost::move(k_lvalue));
node_type n1 = r.extract(r.begin());
test::check_return_type<value_type>::equals_ref(n1.value());
}
template <class X, class Key, class T>
void unordered_map_test(X& r, Key const& k, T const& v)
{
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
BOOST_STATIC_ASSERT(
(boost::is_same<value_type, std::pair<key_type const, T> >::value));
// iterator pointer / const_pointer_type
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
const_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
const_local_iterator>::type const_local_iterator_pointer;
BOOST_STATIC_ASSERT((boost::is_same<value_type*, iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, const_iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type*, local_iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
typedef BOOST_DEDUCED_TYPENAME X::node_type node_type;
typedef BOOST_DEDUCED_TYPENAME node_type::key_type node_key_type;
typedef BOOST_DEDUCED_TYPENAME node_type::mapped_type node_mapped_type;
BOOST_STATIC_ASSERT((boost::is_same<Key, node_key_type>::value));
BOOST_STATIC_ASSERT((boost::is_same<T, node_mapped_type>::value));
// Superfluous,but just to make sure.
BOOST_STATIC_ASSERT((!boost::is_const<node_key_type>::value));
// Calling functions
r.insert(std::pair<Key const, T>(k, v));
r.insert(r.begin(), std::pair<Key const, T>(k, v));
std::pair<Key const, T> const value(k, v);
r.insert(value);
r.insert(r.end(), value);
Key k_lvalue(k);
T v_lvalue(v);
// Emplace
r.emplace(k, v);
r.emplace(k_lvalue, v_lvalue);
r.emplace(rvalue(k), rvalue(v));
r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k),
boost::make_tuple(v));
// Emplace with hint
r.emplace_hint(r.begin(), k, v);
r.emplace_hint(r.begin(), k_lvalue, v_lvalue);
r.emplace_hint(r.begin(), rvalue(k), rvalue(v));
r.emplace_hint(r.begin(), boost::unordered::piecewise_construct,
boost::make_tuple(k), boost::make_tuple(v));
// Extract
test::check_return_type<node_type>::equals(r.extract(r.begin()));
r.emplace(k, v);
test::check_return_type<node_type>::equals(r.extract(k));
r.emplace(k, v);
node_type n1 = r.extract(r.begin());
test::check_return_type<key_type>::equals_ref(n1.key());
test::check_return_type<T>::equals_ref(n1.mapped());
node_type n2 = boost::move(n1);
r.insert(boost::move(n2));
r.insert(r.extract(r.begin()));
n2 = r.extract(r.begin());
r.insert(r.begin(), boost::move(n2));
r.insert(r.end(), r.extract(r.begin()));
node_type n = r.extract(r.begin());
test::check_return_type<node_key_type>::equals_ref(n.key());
test::check_return_type<node_mapped_type>::equals_ref(n.mapped());
}
template <class X> void equality_test(X& r)
{
X const a = r, b = r;
test::check_return_type<bool>::equals(a == b);
test::check_return_type<bool>::equals(a != b);
test::check_return_type<bool>::equals(boost::operator==(a, b));
test::check_return_type<bool>::equals(boost::operator!=(a, b));
}
template <class X, class T> void unordered_unique_test(X& r, T const& t)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
typedef BOOST_DEDUCED_TYPENAME X::node_type node_type;
typedef BOOST_DEDUCED_TYPENAME X::insert_return_type insert_return_type;
// insert_return_type
// TODO;
// boost::function_requires<
// boost::MoveConstructibleConcept<insert_return_type>
// >();
// TODO;
// boost::function_requires<
// boost::MoveAssignableConcept<insert_return_type>
// >();
boost::function_requires<
boost::DefaultConstructibleConcept<insert_return_type> >();
// TODO:
// boost::function_requires<
// boost::DestructibleConcept<insert_return_type>
// >();
insert_return_type insert_return, insert_return2;
test::check_return_type<bool>::equals(insert_return.inserted);
test::check_return_type<iterator>::equals(insert_return.position);
test::check_return_type<node_type>::equals_ref(insert_return.node);
boost::swap(insert_return, insert_return2);
}
template <class X, class T> void unordered_equivalent_test(X& r, T const& t)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<iterator>::equals(r.insert(t));
test::check_return_type<iterator>::equals(r.emplace(t));
}
template <class X, class Key, class T>
void unordered_map_functions(X&, Key const& k, T const& v)
{
typedef BOOST_DEDUCED_TYPENAME X::mapped_type mapped_type;
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
X a;
test::check_return_type<mapped_type>::equals_ref(a[k]);
test::check_return_type<mapped_type>::equals_ref(a[rvalue(k)]);
test::check_return_type<mapped_type>::equals_ref(a.at(k));
test::check_return_type<std::pair<iterator, bool> >::equals(
a.try_emplace(k, v));
test::check_return_type<std::pair<iterator, bool> >::equals(
a.try_emplace(rvalue(k), v));
test::check_return_type<iterator>::equals(a.try_emplace(a.begin(), k, v));
test::check_return_type<iterator>::equals(
a.try_emplace(a.begin(), rvalue(k), v));
test::check_return_type<std::pair<iterator, bool> >::equals(
a.insert_or_assign(k, v));
test::check_return_type<std::pair<iterator, bool> >::equals(
a.insert_or_assign(rvalue(k), v));
test::check_return_type<iterator>::equals(
a.insert_or_assign(a.begin(), k, v));
test::check_return_type<iterator>::equals(
a.insert_or_assign(a.begin(), rvalue(k), v));
X const b = a;
test::check_return_type<mapped_type const>::equals_ref(b.at(k));
}
template <class X, class Key, class Hash, class Pred>
void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
{
unordered_destructible_test(x);
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
typedef BOOST_DEDUCED_TYPENAME X::hasher hasher;
typedef BOOST_DEDUCED_TYPENAME X::key_equal key_equal;
typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<iterator>::type
iterator_category;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type
iterator_difference;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<iterator>::type
iterator_reference;
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
local_iterator>::type local_iterator_category;
typedef BOOST_DEDUCED_TYPENAME
boost::iterator_difference<local_iterator>::type local_iterator_difference;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<local_iterator>::type
local_iterator_reference;
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
const_iterator>::type const_iterator_category;
typedef BOOST_DEDUCED_TYPENAME
boost::iterator_difference<const_iterator>::type const_iterator_difference;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
const_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<const_iterator>::type
const_iterator_reference;
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
const_local_iterator>::type const_local_iterator_category;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
const_local_iterator>::type const_local_iterator_difference;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
const_local_iterator>::type const_local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<
const_local_iterator>::type const_local_iterator_reference;
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value));
// boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
// boost::function_requires<boost::AssignableConcept<key_type> >();
BOOST_STATIC_ASSERT((boost::is_same<Hash, hasher>::value));
test::check_return_type<std::size_t>::equals(hf(k));
BOOST_STATIC_ASSERT((boost::is_same<Pred, key_equal>::value));
test::check_return_type<bool>::convertible(eq(k, k));
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
BOOST_STATIC_ASSERT(
(boost::is_same<local_iterator_category, iterator_category>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<local_iterator_difference, iterator_difference>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<local_iterator_pointer, iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<local_iterator_reference, iterator_reference>::value));
boost::function_requires<
boost::InputIteratorConcept<const_local_iterator> >();
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_category,
const_iterator_category>::value));
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_difference,
const_iterator_difference>::value));
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_pointer,
const_iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_reference,
const_iterator_reference>::value));
X a;
allocator_type m = a.get_allocator();
// Constructors
X(10, hf, eq);
X a1(10, hf, eq);
X(10, hf);
X a2(10, hf);
X(10);
X a3(10);
X();
X a4;
X(10, hf, eq, m);
X a1a(10, hf, eq, m);
X(10, hf, m);
X a2a(10, hf, m);
X(10, m);
X a3a(10, m);
(X(m));
X a4a(m);
test::check_return_type<size_type>::equals(a.erase(k));
const_iterator q1 = a.cbegin(), q2 = a.cend();
test::check_return_type<iterator>::equals(a.erase(q1, q2));
TEST_NOEXCEPT_EXPR(a.clear());
a.clear();
X const b;
test::check_return_type<hasher>::equals(b.hash_function());
test::check_return_type<key_equal>::equals(b.key_eq());
test::check_return_type<iterator>::equals(a.find(k));
test::check_return_type<const_iterator>::equals(b.find(k));
test::check_return_type<size_type>::equals(b.count(k));
test::check_return_type<std::pair<iterator, iterator> >::equals(
a.equal_range(k));
test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
b.equal_range(k));
test::check_return_type<size_type>::equals(b.bucket_count());
test::check_return_type<size_type>::equals(b.max_bucket_count());
test::check_return_type<size_type>::equals(b.bucket(k));
test::check_return_type<size_type>::equals(b.bucket_size(0));
test::check_return_type<local_iterator>::equals(a.begin(0));
test::check_return_type<const_local_iterator>::equals(b.begin(0));
test::check_return_type<local_iterator>::equals(a.end(0));
test::check_return_type<const_local_iterator>::equals(b.end(0));
test::check_return_type<const_local_iterator>::equals(a.cbegin(0));
test::check_return_type<const_local_iterator>::equals(b.cbegin(0));
test::check_return_type<const_local_iterator>::equals(a.cend(0));
test::check_return_type<const_local_iterator>::equals(b.cend(0));
test::check_return_type<float>::equals(b.load_factor());
test::check_return_type<float>::equals(b.max_load_factor());
a.max_load_factor((float)2.0);
a.rehash(100);
a.merge(a2);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
a.merge(rvalue_default<X>());
#endif
// Avoid unused variable warnings:
sink(a);
sink(a1);
sink(a2);
sink(a3);
sink(a4);
sink(a1a);
sink(a2a);
sink(a3a);
sink(a4a);
}
template <class X, class Key, class T, class Hash, class Pred>
void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
{
unordered_test(x, k, hf, eq);
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
X a;
allocator_type m = a.get_allocator();
BOOST_DEDUCED_TYPENAME X::value_type* i = 0;
BOOST_DEDUCED_TYPENAME X::value_type* j = 0;
// Constructors
X(i, j, 10, hf, eq);
X a5(i, j, 10, hf, eq);
X(i, j, 10, hf);
X a6(i, j, 10, hf);
X(i, j, 10);
X a7(i, j, 10);
X(i, j);
X a8(i, j);
X(i, j, 10, hf, eq, m);
X a5a(i, j, 10, hf, eq, m);
X(i, j, 10, hf, m);
X a6a(i, j, 10, hf, m);
X(i, j, 10, m);
X a7a(i, j, 10, m);
// Not specified for some reason (maybe ambiguity with another constructor?)
// X(i, j, m);
// X a8a(i, j, m);
// sink(a8a);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
std::size_t min_buckets = 10;
X({t});
X({t}, min_buckets);
X({t}, min_buckets, hf);
X({t}, min_buckets, hf, eq);
// X({t}, m);
X({t}, min_buckets, m);
X({t}, min_buckets, hf, m);
X({t}, min_buckets, hf, eq, m);
#endif
X const b;
sink(X(b));
X a9(b);
a = b;
sink(X(b, m));
X a9a(b, m);
X b1;
b1.insert(t);
X a9b(b1);
sink(a9b);
X a9c(b1, m);
sink(a9c);
const_iterator q = a.cbegin();
test::check_return_type<iterator>::equals(a.insert(q, t));
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
a.insert(i, j);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
std::initializer_list<T> list = {t};
a.insert(list);
a.insert({t, t, t});
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900) && \
(!defined(__clang__) || __clang_major__ >= 4 || \
(__clang_major__ == 3 && __clang_minor__ >= 4))
a.insert({});
a.insert({t});
a.insert({t, t});
#endif
#endif
X a10;
a10.insert(t);
q = a10.cbegin();
test::check_return_type<iterator>::equals(a10.erase(q));
// Avoid unused variable warnings:
sink(a);
sink(a5);
sink(a6);
sink(a7);
sink(a8);
sink(a9);
sink(a5a);
sink(a6a);
sink(a7a);
sink(a9a);
typedef BOOST_DEDUCED_TYPENAME X::node_type node_type;
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
node_type const n_const = a.extract(a.begin());
test::check_return_type<allocator_type>::equals(n_const.get_allocator());
}
template <class X, class Key, class T, class Hash, class Pred>
void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
{
unordered_test(x, k, hf, eq);
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
X x1(rvalue_default<X>());
X x2(boost::move(x1));
x1 = rvalue_default<X>();
x2 = boost::move(x1);
#endif
X a;
allocator_type m = a.get_allocator();
test::minimal::constructor_param* i = 0;
test::minimal::constructor_param* j = 0;
// Constructors
X(i, j, 10, hf, eq);
X a5(i, j, 10, hf, eq);
X(i, j, 10, hf);
X a6(i, j, 10, hf);
X(i, j, 10);
X a7(i, j, 10);
X(i, j);
X a8(i, j);
X(i, j, 10, hf, eq, m);
X a5a(i, j, 10, hf, eq, m);
X(i, j, 10, hf, m);
X a6a(i, j, 10, hf, m);
X(i, j, 10, m);
X a7a(i, j, 10, m);
// Not specified for some reason (maybe ambiguity with another constructor?)
// X(i, j, m);
// X a8a(i, j, m);
// sink(a8a);
const_iterator q = a.cbegin();
test::minimal::constructor_param v;
a.emplace(v);
test::check_return_type<iterator>::equals(a.emplace_hint(q, v));
T v1(v);
a.emplace(boost::move(v1));
T v2(v);
a.insert(boost::move(v2));
T v3(v);
test::check_return_type<iterator>::equals(a.emplace_hint(q, boost::move(v3)));
T v4(v);
test::check_return_type<iterator>::equals(a.insert(q, boost::move(v4)));
a.insert(i, j);
X a10;
T v5(v);
a10.insert(boost::move(v5));
q = a10.cbegin();
test::check_return_type<iterator>::equals(a10.erase(q));
// Avoid unused variable warnings:
sink(a);
sink(a5);
sink(a6);
sink(a7);
sink(a8);
sink(a5a);
sink(a6a);
sink(a7a);
sink(a10);
}
template <class X, class T> void unordered_set_member_test(X& x, T& t)
{
X x1(x);
x1.insert(t);
x1.begin()->dummy_member();
x1.cbegin()->dummy_member();
}
template <class X, class T> void unordered_map_member_test(X& x, T& t)
{
X x1(x);
x1.insert(t);
x1.begin()->first.dummy_member();
x1.cbegin()->first.dummy_member();
x1.begin()->second.dummy_member();
x1.cbegin()->second.dummy_member();
}