[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#if defined(BOOST_MSVC)
#pragma warning(disable : 4512) // assignment operator could not be generated
#endif
test::seed_t initialize_seed(12847);
template <class T> struct self_assign_base : public test::exception_base
{
test::random_values<T> values;
self_assign_base(std::size_t count = 0) : values(count, test::limited_range)
{
}
typedef T data_type;
T init() const { return T(values.begin(), values.end()); }
void run(T& x) const
{
x = x;
DISABLE_EXCEPTIONS;
test::check_container(x, values);
test::check_equivalent_keys(x);
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
{
test::check_equivalent_keys(x);
}
};
template <class T> struct self_assign_test1 : self_assign_base<T>
{
};
template <class T> struct self_assign_test2 : self_assign_base<T>
{
self_assign_test2() : self_assign_base<T>(100) {}
};
template <class T> struct assign_base : public test::exception_base
{
test::random_values<T> x_values, y_values;
T x, y;
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
: x_values(), y_values(),
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
{
x.max_load_factor(mlf1);
y.max_load_factor(mlf2);
}
typedef T data_type;
T init() const { return T(x); }
void run(T& x1) const
{
x1 = y;
DISABLE_EXCEPTIONS;
test::check_container(x1, y_values);
test::check_equivalent_keys(x1);
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x1) const
{
test::check_equivalent_keys(x1);
// If the container is empty at the point of the exception, the
// internal structure is hidden, this exposes it, at the cost of
// messing up the data.
if (x_values.size()) {
T& x2 = const_cast<T&>(x1);
x2.emplace(*x_values.begin());
test::check_equivalent_keys(x2);
}
}
};
template <class T> struct assign_values : assign_base<T>
{
assign_values(unsigned int count1, unsigned int count2, int tag1, int tag2,
test::random_generator gen = test::default_generator, float mlf1 = 1.0,
float mlf2 = 1.0)
: assign_base<T>(tag1, tag2, mlf1, mlf2)
{
this->x_values.fill(count1, gen);
this->y_values.fill(count2, gen);
this->x.insert(this->x_values.begin(), this->x_values.end());
this->y.insert(this->y_values.begin(), this->y_values.end());
}
};
template <class T> struct assign_test1 : assign_values<T>
{
assign_test1() : assign_values<T>(0, 0, 0, 0) {}
};
template <class T> struct assign_test2 : assign_values<T>
{
assign_test2() : assign_values<T>(60, 0, 0, 0) {}
};
template <class T> struct assign_test2a : assign_values<T>
{
assign_test2a() : assign_values<T>(60, 0, 0, 0, test::limited_range) {}
};
template <class T> struct assign_test3 : assign_values<T>
{
assign_test3() : assign_values<T>(0, 60, 0, 0) {}
};
template <class T> struct assign_test3a : assign_values<T>
{
assign_test3a() : assign_values<T>(0, 60, 0, 0, test::limited_range) {}
};
template <class T> struct assign_test4 : assign_values<T>
{
assign_test4() : assign_values<T>(10, 10, 1, 2) {}
};
template <class T> struct assign_test4a : assign_values<T>
{
assign_test4a() : assign_values<T>(10, 100, 1, 2) {}
};
template <class T> struct assign_test4b : assign_values<T>
{
assign_test4b() : assign_values<T>(10, 100, 1, 2, test::limited_range) {}
};
template <class T> struct assign_test5 : assign_values<T>
{
assign_test5()
: assign_values<T>(5, 60, 0, 0, test::default_generator, 1.0f, 0.1f)
{
}
};
template <class T> struct equivalent_test1 : assign_base<T>
{
equivalent_test1() : assign_base<T>(0, 0)
{
test::random_values<T> x_values2(10);
this->x_values.insert(x_values2.begin(), x_values2.end());
this->x_values.insert(x_values2.begin(), x_values2.end());
test::random_values<T> y_values2(10);
this->y_values.insert(y_values2.begin(), y_values2.end());
this->y_values.insert(y_values2.begin(), y_values2.end());
this->x.insert(this->x_values.begin(), this->x_values.end());
this->y.insert(this->y_values.begin(), this->y_values.end());
}
};
// clang-format off
EXCEPTION_TESTS_REPEAT(5,
(self_assign_test1)(self_assign_test2)
(assign_test1)(assign_test2)(assign_test2a)
(assign_test3)(assign_test3a)
(assign_test4)(assign_test4a)(assign_test4b)
(assign_test5)
(equivalent_test1),
CONTAINER_SEQ)
// clang-format on
RUN_TESTS()

View File

@@ -0,0 +1,212 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/input_iterator.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
template <typename T> inline void avoid_unused_warning(T const&) {}
test::seed_t initialize_seed(91274);
struct objects
{
test::exception::object obj;
test::exception::hash hash;
test::exception::equal_to equal_to;
test::exception::allocator<test::exception::object> allocator;
};
template <class T> struct construct_test1 : public objects, test::exception_base
{
void run() const
{
T x;
DISABLE_EXCEPTIONS;
BOOST_TEST(x.empty());
test::check_equivalent_keys(x);
}
};
template <class T> struct construct_test2 : public objects, test::exception_base
{
void run() const
{
T x(300);
DISABLE_EXCEPTIONS;
BOOST_TEST(x.empty());
test::check_equivalent_keys(x);
}
};
template <class T> struct construct_test3 : public objects, test::exception_base
{
void run() const
{
T x(0, hash);
DISABLE_EXCEPTIONS;
BOOST_TEST(x.empty());
test::check_equivalent_keys(x);
}
};
template <class T> struct construct_test4 : public objects, test::exception_base
{
void run() const
{
T x(0, hash, equal_to);
DISABLE_EXCEPTIONS;
BOOST_TEST(x.empty());
test::check_equivalent_keys(x);
}
};
template <class T> struct construct_test5 : public objects, test::exception_base
{
void run() const
{
T x(50, hash, equal_to, allocator);
DISABLE_EXCEPTIONS;
BOOST_TEST(x.empty());
test::check_equivalent_keys(x);
}
};
template <class T> struct construct_test6 : public objects, test::exception_base
{
void run() const
{
T x(allocator);
DISABLE_EXCEPTIONS;
BOOST_TEST(x.empty());
test::check_equivalent_keys(x);
}
};
template <class T> struct range : public test::exception_base
{
test::random_values<T> values;
range() : values(5, test::limited_range) {}
range(unsigned int count) : values(count, test::limited_range) {}
};
template <class T> struct range_construct_test1 : public range<T>, objects
{
void run() const
{
T x(this->values.begin(), this->values.end());
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct range_construct_test2 : public range<T>, objects
{
void run() const
{
T x(this->values.begin(), this->values.end(), 0);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct range_construct_test3 : public range<T>, objects
{
void run() const
{
T x(this->values.begin(), this->values.end(), 0, hash);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct range_construct_test4 : public range<T>, objects
{
void run() const
{
T x(this->values.begin(), this->values.end(), 100, hash, equal_to);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
// Need to run at least one test with a fairly large number
// of objects in case it triggers a rehash.
template <class T> struct range_construct_test5 : public range<T>, objects
{
range_construct_test5() : range<T>(60) {}
void run() const
{
T x(this->values.begin(), this->values.end(), 0, hash, equal_to, allocator);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct input_range_construct_test : public range<T>, objects
{
input_range_construct_test() : range<T>(60) {}
void run() const
{
BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
begin = this->values.begin(),
end = this->values.end();
T x(test::input_iterator(begin), test::input_iterator(end), 0, hash,
equal_to, allocator);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct copy_range_construct_test : public range<T>, objects
{
copy_range_construct_test() : range<T>(60) {}
void run() const
{
T x(test::copy_iterator(this->values.begin()),
test::copy_iterator(this->values.end()), 0, hash, equal_to, allocator);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
// clang-format off
EXCEPTION_TESTS(
(construct_test1)(construct_test2)(construct_test3)(construct_test4)
(construct_test5)(construct_test6)(range_construct_test1)
(range_construct_test2)(range_construct_test3)(range_construct_test4)
(range_construct_test5)(input_range_construct_test)
(copy_range_construct_test),
CONTAINER_SEQ)
// clang-format on
RUN_TESTS()

View File

@@ -0,0 +1,44 @@
// Copyright 2006-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)
// clang-format off
#include "../helpers/prefix.hpp"
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include "../helpers/postfix.hpp"
// clang-format on
#include "../objects/exception.hpp"
typedef boost::unordered_set<test::exception::object, test::exception::hash,
test::exception::equal_to,
test::exception::allocator<test::exception::object> >
test_set;
typedef boost::unordered_multiset<test::exception::object,
test::exception::hash, test::exception::equal_to,
test::exception::allocator2<test::exception::object> >
test_multiset;
typedef boost::unordered_map<test::exception::object, test::exception::object,
test::exception::hash, test::exception::equal_to,
test::exception::allocator2<test::exception::object> >
test_map;
typedef boost::unordered_multimap<test::exception::object,
test::exception::object, test::exception::hash, test::exception::equal_to,
test::exception::allocator<test::exception::object> >
test_multimap;
typedef boost::unordered_set<
std::pair<test::exception::object, test::exception::object>,
test::exception::hash, test::exception::equal_to,
test::exception::allocator<test::exception::object> >
test_pair_set;
typedef boost::unordered_multiset<
std::pair<test::exception::object, test::exception::object>,
test::exception::hash, test::exception::equal_to,
test::exception::allocator2<test::exception::object> >
test_pair_multiset;
#define CONTAINER_SEQ (test_set)(test_multiset)(test_map)(test_multimap)
#define CONTAINER_PAIR_SEQ \
(test_pair_set)(test_pair_multiset)(test_map)(test_multimap)

View File

@@ -0,0 +1,110 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
template <typename T> inline void avoid_unused_warning(T const&) {}
test::seed_t initialize_seed(73041);
template <class T> struct copy_test1 : public test::exception_base
{
T x;
void run() const
{
T y(x);
DISABLE_EXCEPTIONS;
BOOST_TEST(y.empty());
test::check_equivalent_keys(y);
}
};
template <class T> struct copy_test2 : public test::exception_base
{
test::random_values<T> values;
T x;
copy_test2() : values(5, test::limited_range), x(values.begin(), values.end())
{
}
void run() const
{
T y(x);
DISABLE_EXCEPTIONS;
test::check_container(y, this->values);
test::check_equivalent_keys(y);
}
};
template <class T> struct copy_test3 : public test::exception_base
{
test::random_values<T> values;
T x;
copy_test3() : values(100), x(values.begin(), values.end()) {}
void run() const
{
T y(x);
DISABLE_EXCEPTIONS;
test::check_container(y, this->values);
test::check_equivalent_keys(y);
}
};
template <class T> struct copy_test3a : public test::exception_base
{
test::random_values<T> values;
T x;
copy_test3a()
: values(100, test::limited_range), x(values.begin(), values.end())
{
}
void run() const
{
T y(x);
DISABLE_EXCEPTIONS;
test::check_container(y, this->values);
test::check_equivalent_keys(y);
}
};
template <class T> struct copy_with_allocator_test : public test::exception_base
{
test::random_values<T> values;
T x;
test::exception::allocator<test::exception::object> allocator;
copy_with_allocator_test() : values(100), x(values.begin(), values.end()) {}
void run() const
{
T y(x, allocator);
DISABLE_EXCEPTIONS;
test::check_container(y, this->values);
test::check_equivalent_keys(y);
}
};
// clang-format off
EXCEPTION_TESTS(
(copy_test1)(copy_test2)(copy_test3)(copy_test3a)(copy_with_allocator_test),
CONTAINER_SEQ)
// clang-format on
RUN_TESTS()

View File

@@ -0,0 +1,56 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/helpers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
test::seed_t initialize_seed(835193);
template <class T> struct erase_test_base : public test::exception_base
{
test::random_values<T> values;
erase_test_base(unsigned int count = 5) : values(count, test::limited_range)
{
}
typedef T data_type;
data_type init() const { return T(values.begin(), values.end()); }
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
{
std::string scope(test::scope);
BOOST_TEST(scope.find("hash::") != std::string::npos ||
scope.find("equal_to::") != std::string::npos ||
scope == "operator==(object, object)");
test::check_equivalent_keys(x);
}
};
template <class T> struct erase_by_key_test1 : public erase_test_base<T>
{
void run(T& x) const
{
typedef BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
iterator;
for (iterator it = this->values.begin(), end = this->values.end();
it != end; ++it) {
x.erase(test::get_key<T>(*it));
}
DISABLE_EXCEPTIONS;
BOOST_TEST(x.empty());
test::check_equivalent_keys(x);
}
};
EXCEPTION_TESTS((erase_by_key_test1), CONTAINER_SEQ)
RUN_TESTS()

View File

@@ -0,0 +1,414 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/helpers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/strong.hpp"
#include "../helpers/tracker.hpp"
#include <cmath>
#include <string>
test::seed_t initialize_seed(747373);
// Fill in a container so that it's about to rehash
template <typename T> void rehash_prep(T& x)
{
using namespace std;
typedef BOOST_DEDUCED_TYPENAME T::size_type size_type;
x.max_load_factor(0.25);
size_type bucket_count = x.bucket_count();
size_type initial_elements = static_cast<size_type>(
ceil((double)bucket_count * (double)x.max_load_factor()) - 1);
test::random_values<T> v(initial_elements);
x.insert(v.begin(), v.end());
BOOST_TEST(bucket_count == x.bucket_count());
}
// Overload to generate inserters that need type information.
template <typename Inserter, typename T>
Inserter generate(Inserter inserter, T&)
{
return inserter;
}
// Get the iterator returned from an insert/emplace.
template <typename T> T get_iterator(T const& x) { return x; }
template <typename T> T get_iterator(std::pair<T, bool> const& x)
{
return x.first;
}
// Generic insert exception test for typical single element inserts..
template <typename T, typename Inserter, typename Values>
void insert_exception_test_impl(T x, Inserter insert, Values const& v)
{
test::strong<T> strong;
test::ordered<T> tracker;
tracker.insert(x.begin(), x.end());
try {
ENABLE_EXCEPTIONS;
for (typename Values::const_iterator it = v.begin(); it != v.end(); ++it) {
strong.store(x, test::detail::tracker.count_allocations);
insert(x, it);
}
} catch (...) {
test::check_equivalent_keys(x);
insert.exception_check(x, strong);
throw;
}
test::check_equivalent_keys(x);
insert.track(tracker, v.begin(), v.end());
tracker.compare(x);
}
// Simple insert exception test
template <typename T, typename Inserter>
void insert_exception_test(T*, Inserter insert, test::random_generator gen)
{
for (int i = 0; i < 5; ++i) {
test::random_values<T> v(10, gen);
T x;
EXCEPTION_LOOP(insert_exception_test_impl(x, generate(insert, x), v));
}
}
// Insert into a container which is about to hit its max load, so that it
// rehashes.
template <typename T, typename Inserter>
void insert_rehash_exception_test(
T*, Inserter insert, test::random_generator gen)
{
for (int i = 0; i < 5; ++i) {
T x;
rehash_prep(x);
test::random_values<T> v2(5, gen);
EXCEPTION_LOOP(insert_exception_test_impl(x, generate(insert, x), v2));
}
}
// Various methods for inserting a single element
struct inserter_base
{
template <typename T> void exception_check(T& x, test::strong<T>& strong)
{
std::string scope(test::scope);
if (scope.find("hash::operator()") == std::string::npos)
strong.test(x, test::detail::tracker.count_allocations);
}
template <typename T, typename Iterator>
void track(T& tracker, Iterator begin, Iterator end)
{
tracker.insert(begin, end);
}
};
struct insert_lvalue_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.insert(*it);
}
} insert_lvalue;
struct insert_lvalue_begin_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.insert(x.begin(), *it);
}
} insert_lvalue_begin;
struct insert_lvalue_end_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.insert(x.end(), *it);
}
} insert_lvalue_end;
struct insert_lvalue_pos_type
{
template <typename T> struct impl : inserter_base
{
typename T::iterator pos;
impl(T& x) : pos(x.begin()) {}
template <typename Iterator> void operator()(T& x, Iterator it)
{
pos = get_iterator(x.insert(pos, *it));
}
};
template <typename T> friend impl<T> generate(insert_lvalue_pos_type, T& x)
{
return impl<T>(x);
}
} insert_lvalue_pos;
struct insert_single_item_range_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.insert(it, test::next(it));
}
} insert_single_item_range;
struct emplace_lvalue_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.emplace(*it);
}
} emplace_lvalue;
struct emplace_lvalue_begin_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.emplace_hint(x.begin(), *it);
}
} emplace_lvalue_begin;
struct emplace_lvalue_end_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.emplace_hint(x.end(), *it);
}
} emplace_lvalue_end;
struct emplace_lvalue_pos_type
{
template <typename T> struct impl : inserter_base
{
typename T::iterator pos;
impl(T& x) : pos(x.begin()) {}
template <typename Iterator> void operator()(T& x, Iterator it)
{
pos = get_iterator(x.emplace_hint(pos, *it));
}
};
template <typename T> friend impl<T> generate(emplace_lvalue_pos_type, T& x)
{
return impl<T>(x);
}
} emplace_lvalue_pos;
// Run the exception tests in various combinations.
test_set* test_set_;
test_multiset* test_multiset_;
test_map* test_map_;
test_multimap* test_multimap_;
using test::default_generator;
using test::limited_range;
using test::generate_collisions;
// clang-format off
UNORDERED_TEST(insert_exception_test,
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
((insert_lvalue)(insert_lvalue_begin)(insert_lvalue_end)
(insert_lvalue_pos)(insert_single_item_range)
(emplace_lvalue)(emplace_lvalue_begin)(emplace_lvalue_end)
(emplace_lvalue_pos)
)
((default_generator)(limited_range)(generate_collisions))
)
UNORDERED_TEST(insert_rehash_exception_test,
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
((insert_lvalue)(insert_lvalue_begin)(insert_lvalue_end)
(insert_lvalue_pos)(insert_single_item_range)
(emplace_lvalue)(emplace_lvalue_begin)(emplace_lvalue_end)
(emplace_lvalue_pos)
)
((default_generator)(limited_range)(generate_collisions))
)
// clang-format on
// Repeat insert tests with pairs
struct pair_emplace_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(it->first), boost::make_tuple(it->second));
}
} pair_emplace;
struct pair_emplace2_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.emplace_hint(x.begin(), boost::unordered::piecewise_construct,
boost::make_tuple(it->first),
boost::make_tuple(it->second.tag1_, it->second.tag2_));
}
} pair_emplace2;
test_pair_set* test_pair_set_;
test_pair_multiset* test_pair_multiset_;
// clang-format off
UNORDERED_TEST(insert_exception_test,
((test_pair_set_)(test_pair_multiset_)(test_map_)(test_multimap_))
((pair_emplace)(pair_emplace2))
((default_generator)(limited_range)(generate_collisions))
)
UNORDERED_TEST(insert_rehash_exception_test,
((test_pair_set_)(test_pair_multiset_)(test_map_)(test_multimap_))
((pair_emplace)(pair_emplace2))
((default_generator)(limited_range)(generate_collisions))
)
// clang-format on
// Test inserting using operator[]
struct try_emplace_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.try_emplace(it->first, it->second);
}
} try_emplace;
struct try_emplace2_type : inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.try_emplace(it->first, it->second.tag1_, it->second.tag2_);
}
} try_emplace2;
struct map_inserter_base
{
template <typename T> void exception_check(T& x, test::strong<T>& strong)
{
std::string scope(test::scope);
if (scope.find("hash::operator()") == std::string::npos &&
scope.find("::operator=") == std::string::npos)
strong.test(x, test::detail::tracker.count_allocations);
}
template <typename T, typename Iterator>
void track(T& tracker, Iterator begin, Iterator end)
{
for (; begin != end; ++begin) {
tracker[begin->first] = begin->second;
}
}
};
struct map_insert_operator_type : map_inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x[it->first] = it->second;
}
} map_insert_operator;
struct map_insert_or_assign_type : map_inserter_base
{
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
{
x.insert_or_assign(it->first, it->second);
}
} map_insert_or_assign;
// clang-format off
UNORDERED_TEST(insert_exception_test,
((test_map_))
((try_emplace)(try_emplace2)(map_insert_operator)(map_insert_or_assign))
((default_generator)(limited_range)(generate_collisions))
)
UNORDERED_TEST(insert_rehash_exception_test,
((test_map_))
((try_emplace)(try_emplace2)(map_insert_operator)(map_insert_or_assign))
((default_generator)(limited_range)(generate_collisions))
)
// clang-format on
// Range insert tests
template <typename T, typename Values>
void insert_range_exception_test_impl(T x, Values const& v)
{
test::ordered<T> tracker;
tracker.insert(x.begin(), x.end());
try {
ENABLE_EXCEPTIONS;
x.insert(v.begin(), v.end());
} catch (...) {
test::check_equivalent_keys(x);
throw;
}
test::check_equivalent_keys(x);
tracker.insert(v.begin(), v.end());
tracker.compare(x);
}
template <typename T>
void insert_range_exception_test(T*, test::random_generator gen)
{
for (int i = 0; i < 5; ++i) {
test::random_values<T> v(10, gen);
T x;
EXCEPTION_LOOP(insert_range_exception_test_impl(x, v));
}
}
template <typename T>
void insert_range_rehash_exception_test(T*, test::random_generator gen)
{
for (int i = 0; i < 5; ++i) {
T x;
rehash_prep(x);
test::random_values<T> v2(5, gen);
EXCEPTION_LOOP(insert_range_exception_test_impl(x, v2));
}
}
// clang-format off
UNORDERED_TEST(insert_range_exception_test,
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
((default_generator)(limited_range)(generate_collisions))
)
UNORDERED_TEST(insert_range_rehash_exception_test,
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
((default_generator)(limited_range)(generate_collisions))
)
// clang-format on
RUN_TESTS()

View File

@@ -0,0 +1,103 @@
#include "../helpers/exception_test.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/metafunctions.hpp"
#include "../helpers/random_values.hpp"
#include "./containers.hpp"
template <typename T1, typename T2> void merge_exception_test(T1 x, T2 y)
{
std::size_t size = x.size() + y.size();
try {
ENABLE_EXCEPTIONS;
x.merge(y);
} catch (...) {
test::check_equivalent_keys(x);
test::check_equivalent_keys(y);
throw;
}
// Not a full check, just want to make sure the merge completed.
BOOST_TEST(size == x.size() + y.size());
if (y.size()) {
BOOST_TEST(test::has_unique_keys<T1>::value);
for (typename T2::iterator it = y.begin(); it != y.end(); ++it) {
BOOST_TEST(x.find(test::get_key<T2>(*it)) != x.end());
}
}
test::check_equivalent_keys(x);
test::check_equivalent_keys(y);
}
template <typename T1, typename T2>
void merge_exception_test(T1 const*, T2 const*, std::size_t count12, int tag12,
test::random_generator gen1, test::random_generator gen2)
{
std::size_t count1 = count12 / 256;
std::size_t count2 = count12 % 256;
int tag1 = tag12 / 256;
int tag2 = tag12 % 256;
test::random_values<T1> v1(count1, gen1);
test::random_values<T2> v2(count2, gen2);
T1 x(v1.begin(), v1.end(), 0, test::exception::hash(tag1),
test::exception::equal_to(tag1));
T2 y(v2.begin(), v2.end(), 0, test::exception::hash(tag2),
test::exception::equal_to(tag2));
EXCEPTION_LOOP(merge_exception_test(x, y))
}
boost::unordered_set<test::exception::object, test::exception::hash,
test::exception::equal_to,
test::exception::allocator<test::exception::object> >* test_set_;
boost::unordered_multiset<test::exception::object, test::exception::hash,
test::exception::equal_to,
test::exception::allocator<test::exception::object> >* test_multiset_;
boost::unordered_map<test::exception::object, test::exception::object,
test::exception::hash, test::exception::equal_to,
test::exception::allocator2<test::exception::object> >* test_map_;
boost::unordered_multimap<test::exception::object, test::exception::object,
test::exception::hash, test::exception::equal_to,
test::exception::allocator2<test::exception::object> >* test_multimap_;
using test::default_generator;
using test::generate_collisions;
using test::limited_range;
// clang-format off
UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
((test_set_)(test_multiset_))
((test_set_)(test_multiset_))
((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
((0x0000)(0x0001)(0x0102))
((default_generator)(limited_range))
((default_generator)(limited_range))
)
UNORDERED_MULTI_TEST(map_merge, merge_exception_test,
((test_map_)(test_multimap_))
((test_map_)(test_multimap_))
((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
((0x0101)(0x0200)(0x0201))
((default_generator)(limited_range))
((default_generator)(limited_range))
)
// Run fewer generate_collisions tests, as they're slow.
UNORDERED_MULTI_TEST(set_merge_collisions, merge_exception_test,
((test_set_)(test_multiset_))
((test_set_)(test_multiset_))
((0x0a0a))
((0x0202)(0x0100)(0x0201))
((generate_collisions))
((generate_collisions))
)
UNORDERED_MULTI_TEST(map_merge_collisions, merge_exception_test,
((test_map_)(test_multimap_))
((test_map_)(test_multimap_))
((0x0a0a))
((0x0000)(0x0002)(0x0102))
((generate_collisions))
((generate_collisions))
)
// clang-format on
RUN_TESTS_QUIET()

View File

@@ -0,0 +1,132 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#if defined(BOOST_MSVC)
#pragma warning( \
disable : 4512) // move_assignment operator could not be generated
#endif
test::seed_t initialize_seed(12847);
template <class T> struct move_assign_base : public test::exception_base
{
test::random_values<T> x_values, y_values;
T x, y;
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
move_assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
: x_values(), y_values(),
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
{
x.max_load_factor(mlf1);
y.max_load_factor(mlf2);
}
typedef T data_type;
T init() const { return T(x); }
void run(T& x1) const
{
test::exceptions_enable disable_exceptions(false);
T y1 = y;
disable_exceptions.release();
x1 = boost::move(y1);
DISABLE_EXCEPTIONS;
test::check_container(x1, y_values);
test::check_equivalent_keys(x1);
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x1) const
{
test::check_equivalent_keys(x1);
// If the container is empty at the point of the exception, the
// internal structure is hidden, this exposes it, at the cost of
// messing up the data.
if (x_values.size()) {
T& x2 = const_cast<T&>(x1);
x2.emplace(*x_values.begin());
test::check_equivalent_keys(x2);
}
}
};
template <class T> struct move_assign_values : move_assign_base<T>
{
move_assign_values(unsigned int count1, unsigned int count2, int tag1,
int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
: move_assign_base<T>(tag1, tag2, mlf1, mlf2)
{
this->x_values.fill(count1, test::limited_range);
this->y_values.fill(count2, test::limited_range);
this->x.insert(this->x_values.begin(), this->x_values.end());
this->y.insert(this->y_values.begin(), this->y_values.end());
}
};
template <class T> struct move_assign_test1 : move_assign_values<T>
{
move_assign_test1() : move_assign_values<T>(0, 0, 0, 0) {}
};
template <class T> struct move_assign_test2 : move_assign_values<T>
{
move_assign_test2() : move_assign_values<T>(60, 0, 0, 0) {}
};
template <class T> struct move_assign_test3 : move_assign_values<T>
{
move_assign_test3() : move_assign_values<T>(0, 60, 0, 0) {}
};
template <class T> struct move_assign_test4 : move_assign_values<T>
{
move_assign_test4() : move_assign_values<T>(10, 10, 1, 2) {}
};
template <class T> struct move_assign_test4a : move_assign_values<T>
{
move_assign_test4a() : move_assign_values<T>(10, 100, 1, 2) {}
};
template <class T> struct move_assign_test5 : move_assign_values<T>
{
move_assign_test5() : move_assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
};
template <class T> struct equivalent_test1 : move_assign_base<T>
{
equivalent_test1() : move_assign_base<T>(0, 0)
{
test::random_values<T> x_values2(10, test::limited_range);
this->x_values.insert(x_values2.begin(), x_values2.end());
this->x_values.insert(x_values2.begin(), x_values2.end());
test::random_values<T> y_values2(10, test::limited_range);
this->y_values.insert(y_values2.begin(), y_values2.end());
this->y_values.insert(y_values2.begin(), y_values2.end());
this->x.insert(this->x_values.begin(), this->x_values.end());
this->y.insert(this->y_values.begin(), this->y_values.end());
}
};
// clang-format off
EXCEPTION_TESTS(
(move_assign_test1)(move_assign_test2)(move_assign_test3)
(move_assign_test4)(move_assign_test4a)(move_assign_test5)
(equivalent_test1),
CONTAINER_SEQ)
// clang-format on
RUN_TESTS()

View File

@@ -0,0 +1,133 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/strong.hpp"
#include "../helpers/tracker.hpp"
#include <string>
test::seed_t initialize_seed(3298597);
template <class T> struct rehash_test_base : public test::exception_base
{
test::random_values<T> values;
unsigned int n;
rehash_test_base(unsigned int count = 100, unsigned int n_ = 0)
: values(count, test::limited_range), n(n_)
{
}
typedef T data_type;
typedef test::strong<T> strong_type;
data_type init() const
{
T x(values.begin(), values.end(), n);
return x;
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(
T const& x, strong_type const& strong) const
{
std::string scope(test::scope);
if (scope.find("hash::operator()") == std::string::npos &&
scope.find("equal_to::operator()") == std::string::npos &&
scope != "operator==(object, object)")
strong.test(x);
test::check_equivalent_keys(x);
}
};
template <class T> struct rehash_test0 : rehash_test_base<T>
{
rehash_test0() : rehash_test_base<T>(0) {}
void run(T& x) const
{
x.rehash(0);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct rehash_test1 : rehash_test_base<T>
{
rehash_test1() : rehash_test_base<T>(0) {}
void run(T& x) const
{
x.rehash(200);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct rehash_test2 : rehash_test_base<T>
{
rehash_test2() : rehash_test_base<T>(0, 200) {}
void run(T& x) const
{
x.rehash(0);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct rehash_test3 : rehash_test_base<T>
{
rehash_test3() : rehash_test_base<T>(10, 0) {}
void run(T& x) const
{
x.rehash(200);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct rehash_test4 : rehash_test_base<T>
{
rehash_test4() : rehash_test_base<T>(10, 200) {}
void run(T& x) const
{
x.rehash(0);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
template <class T> struct rehash_test5 : rehash_test_base<T>
{
rehash_test5() : rehash_test_base<T>(200, 10) {}
void run(T& x) const
{
x.rehash(0);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
};
// clang-format off
EXCEPTION_TESTS(
(rehash_test0)(rehash_test1)(rehash_test2)(rehash_test3)(rehash_test4)
(rehash_test5),
CONTAINER_SEQ)
// clang-format on
RUN_TESTS()

View File

@@ -0,0 +1,145 @@
// Copyright 2006-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)
#include "./containers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#if defined(BOOST_MSVC)
#pragma warning(disable : 4512) // assignment operator could not be generated
#endif
test::seed_t initialize_seed(9387);
template <class T> struct self_swap_base : public test::exception_base
{
test::random_values<T> values;
self_swap_base(std::size_t count = 0) : values(count, test::limited_range) {}
typedef T data_type;
T init() const { return T(values.begin(), values.end()); }
void run(T& x) const
{
x.swap(x);
DISABLE_EXCEPTIONS;
test::check_container(x, this->values);
test::check_equivalent_keys(x);
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
{
std::string scope(test::scope);
// TODO: In C++11 exceptions are only allowed in the swap function.
BOOST_TEST(scope == "hash::hash(hash)" ||
scope == "hash::operator=(hash)" ||
scope == "equal_to::equal_to(equal_to)" ||
scope == "equal_to::operator=(equal_to)");
test::check_equivalent_keys(x);
}
};
template <class T> struct self_swap_test1 : self_swap_base<T>
{
};
template <class T> struct self_swap_test2 : self_swap_base<T>
{
self_swap_test2() : self_swap_base<T>(100) {}
};
template <class T> struct swap_base : public test::exception_base
{
const test::random_values<T> x_values, y_values;
const T initial_x, initial_y;
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
swap_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
: x_values(count1, test::limited_range),
y_values(count2, test::limited_range),
initial_x(x_values.begin(), x_values.end(), 0, hasher(tag1),
key_equal(tag1), allocator_type(tag1)),
initial_y(y_values.begin(), y_values.end(), 0, hasher(tag2),
key_equal(tag2),
allocator_type(T::allocator_type::propagate_on_container_swap::value
? tag2
: tag1))
{
}
struct data_type
{
data_type(T const& x_, T const& y_) : x(x_), y(y_) {}
T x, y;
};
data_type init() const { return data_type(initial_x, initial_y); }
void run(data_type& d) const
{
try {
d.x.swap(d.y);
} catch (std::runtime_error) {
}
DISABLE_EXCEPTIONS;
test::check_container(d.x, this->y_values);
test::check_equivalent_keys(d.x);
test::check_container(d.y, this->x_values);
test::check_equivalent_keys(d.y);
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(data_type const& d) const
{
std::string scope(test::scope);
// TODO: In C++11 exceptions are only allowed in the swap function.
BOOST_TEST(scope == "hash::hash(hash)" ||
scope == "hash::operator=(hash)" ||
scope == "equal_to::equal_to(equal_to)" ||
scope == "equal_to::operator=(equal_to)");
test::check_equivalent_keys(d.x);
test::check_equivalent_keys(d.y);
}
};
template <class T> struct swap_test1 : swap_base<T>
{
swap_test1() : swap_base<T>(0, 0, 0, 0) {}
};
template <class T> struct swap_test2 : swap_base<T>
{
swap_test2() : swap_base<T>(60, 0, 0, 0) {}
};
template <class T> struct swap_test3 : swap_base<T>
{
swap_test3() : swap_base<T>(0, 60, 0, 0) {}
};
template <class T> struct swap_test4 : swap_base<T>
{
swap_test4() : swap_base<T>(10, 10, 1, 2) {}
};
// clang-format off
EXCEPTION_TESTS(
(self_swap_test1)(self_swap_test2)
(swap_test1)(swap_test2)(swap_test3)(swap_test4),
CONTAINER_SEQ)
// clang-format on
RUN_TESTS()