mirror of
https://github.com/boostorg/unordered.git
synced 2025-11-03 09:11:42 +01:00
More tests for unordered associative containers.
[SVN r2959]
This commit is contained in:
29
test/exception/Jamfile.v2
Normal file
29
test/exception/Jamfile.v2
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
# Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
# subject to 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)
|
||||
|
||||
import testing ;
|
||||
|
||||
alias framework : /boost/test//boost_unit_test_framework/<optimization>speed ;
|
||||
|
||||
project unordered-test/exception-tests
|
||||
: requirements
|
||||
<toolset>intel-linux:"<cxxflags>-strict_ansi -cxxlib-icc"
|
||||
;
|
||||
|
||||
test-suite unordered-tests
|
||||
:
|
||||
[ run constructor_tests.cpp framework ]
|
||||
[ run copy_tests.cpp framework ]
|
||||
[ run assign_tests.cpp framework ]
|
||||
[ run insert_tests.cpp framework ]
|
||||
[ run erase_tests.cpp framework ]
|
||||
[ run rehash_tests.cpp framework ]
|
||||
[ run swap_tests.cpp framework : : :
|
||||
<define>BOOST_UNORDERED_SWAP_METHOD=1 : swap_tests1 ]
|
||||
[ run swap_tests.cpp framework : : :
|
||||
<define>BOOST_UNORDERED_SWAP_METHOD=2 : swap_tests2 ]
|
||||
[ run swap_tests.cpp framework : : :
|
||||
<define>BOOST_UNORDERED_SWAP_METHOD=3 : swap_tests3 ]
|
||||
;
|
||||
79
test/exception/assign_tests.cpp
Normal file
79
test/exception/assign_tests.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to 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"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/exception_safety.hpp>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
template <class T>
|
||||
struct self_assign_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
self_assign_base(int count = 0) : values(count) {}
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
void run(T& x) const { x = x; }
|
||||
void check(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
|
||||
{
|
||||
const test::random_values<T> x_values, y_values;
|
||||
const T x,y;
|
||||
|
||||
assign_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
|
||||
: x_values(count1), y_values(count2),
|
||||
x(x_values.begin(), x_values.end(), 0, typename T::hasher(tag1), typename T::key_equal(tag1), typename T::allocator_type(tag1)),
|
||||
y(y_values.begin(), y_values.end(), 0, typename T::hasher(tag2), typename T::key_equal(tag2), typename T::allocator_type(tag2)) {}
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(x); }
|
||||
void run(T& x1) const { x1 = y; }
|
||||
void check(T const& x1) const { test::check_equivalent_keys(x1); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test1 : assign_base<T>
|
||||
{
|
||||
assign_test1() : assign_base<T>(0, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test2 : assign_base<T>
|
||||
{
|
||||
assign_test2() : assign_base<T>(60, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test3 : assign_base<T>
|
||||
{
|
||||
assign_test3() : assign_base<T>(0, 60, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test4 : assign_base<T>
|
||||
{
|
||||
assign_test4() : assign_base<T>(10, 10, 1, 2) {}
|
||||
};
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(self_assign_test1)(self_assign_test2)
|
||||
(assign_test1)(assign_test2)(assign_test3)(assign_test4),
|
||||
CONTAINER_SEQ)
|
||||
119
test/exception/constructor_tests.cpp
Normal file
119
test/exception/constructor_tests.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to 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"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/exception_safety.hpp>
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test2 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(300);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test3 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(0, hash);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test4 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(0, hash, equal_to);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test5 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(50, hash, equal_to, allocator);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
|
||||
range() : values(5) {}
|
||||
range(unsigned int count) : values(count) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_construct_test1 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_construct_test2 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_construct_test3 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0, hash);
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Write a test using an input iterator.
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(construct_test1)(construct_test2)(construct_test3)(construct_test4)(construct_test5)
|
||||
(range_construct_test1)(range_construct_test2)(range_construct_test3)(range_construct_test4)(range_construct_test5),
|
||||
CONTAINER_SEQ)
|
||||
28
test/exception/containers.hpp
Normal file
28
test/exception/containers.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include "../objects/exception.hpp"
|
||||
|
||||
typedef boost::unordered_set<
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> > set;
|
||||
typedef boost::unordered_multiset<
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> > multiset;
|
||||
typedef boost::unordered_map<
|
||||
test::exception::object,
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> > map;
|
||||
typedef boost::unordered_multimap<
|
||||
test::exception::object,
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> > multimap;
|
||||
|
||||
#define CONTAINER_SEQ (set)(multiset)(map)(multimap)
|
||||
51
test/exception/copy_tests.cpp
Normal file
51
test/exception/copy_tests.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to 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"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/exception_safety.hpp>
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
template <class T>
|
||||
struct copy_test1 : public test::exception_base
|
||||
{
|
||||
T x;
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct copy_test2 : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
T x;
|
||||
|
||||
copy_test2() : values(5), x(values.begin(), values.end()) {}
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(copy_test1)(copy_test2)(copy_test3),
|
||||
CONTAINER_SEQ)
|
||||
55
test/exception/erase_tests.cpp
Normal file
55
test/exception/erase_tests.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to 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"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/exception_safety.hpp>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
|
||||
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) {}
|
||||
|
||||
typedef T data_type;
|
||||
|
||||
data_type init() const {
|
||||
return T(values.begin(), values.end());
|
||||
}
|
||||
|
||||
void check(T const& x) const {
|
||||
// TODO: Check that exception was thrown by hash or predicate 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 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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: More tests...
|
||||
// Better test by key.
|
||||
// Test other erase signatures - generally they won't throw, but the standard
|
||||
// does allow them to. And test clear as well.
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(erase_by_key_test1),
|
||||
CONTAINER_SEQ)
|
||||
168
test/exception/insert_tests.cpp
Normal file
168
test/exception/insert_tests.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to 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"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/exception_safety.hpp>
|
||||
#include <string>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
template <class T>
|
||||
struct insert_test_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
insert_test_base(unsigned int count = 5) : values(count) {}
|
||||
|
||||
typedef T data_type;
|
||||
typedef test::strong<T> strong_type;
|
||||
|
||||
data_type init() const {
|
||||
return T();
|
||||
}
|
||||
|
||||
void check(T const& x, strong_type const& strong) const {
|
||||
std::string scope(test::scope);
|
||||
|
||||
if(scope.find_first_of("hash::operator()") == std::string::npos)
|
||||
strong.test(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test1 : public insert_test_base<T>
|
||||
{
|
||||
typedef typename insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
for(typename test::random_values<T>::const_iterator
|
||||
it = this->values.begin(), end = this->values.end(); it != end; ++it)
|
||||
{
|
||||
strong.store(x);
|
||||
x.insert(*it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test2 : public insert_test_base<T>
|
||||
{
|
||||
typedef typename insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
for(typename test::random_values<T>::const_iterator
|
||||
it = this->values.begin(), end = this->values.end(); it != end; ++it)
|
||||
{
|
||||
strong.store(x);
|
||||
x.insert(x.begin(), *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test3 : public insert_test_base<T>
|
||||
{
|
||||
typedef typename insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
// I don't think there's any need for this here.
|
||||
//strong.store(x);
|
||||
x.insert(this->values.begin(), this->values.end());
|
||||
}
|
||||
|
||||
void check(T const& x) const {
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test4 : public insert_test_base<T>
|
||||
{
|
||||
typedef typename insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
for(typename test::random_values<T>::const_iterator
|
||||
it = this->values.begin(), end = this->values.end(); it != end; ++it)
|
||||
{
|
||||
strong.store(x);
|
||||
x.insert(it, boost::next(it));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test_rehash1 : public insert_test_base<T>
|
||||
{
|
||||
typedef typename insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
insert_test_rehash1() : insert_test_base<T>(1000) {}
|
||||
|
||||
T init() const {
|
||||
typedef typename T::size_type size_type;
|
||||
|
||||
T x;
|
||||
x.max_load_factor(0.25);
|
||||
size_type bucket_count = x.bucket_count();
|
||||
size_type initial_elements = static_cast<size_type>(
|
||||
std::ceil(bucket_count * x.max_load_factor()) - 1);
|
||||
BOOST_REQUIRE(initial_elements < this->values.size());
|
||||
x.insert(this->values.begin(),
|
||||
boost::next(this->values.begin(), initial_elements));
|
||||
BOOST_REQUIRE(bucket_count == x.bucket_count());
|
||||
return x;
|
||||
}
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
typename T::size_type bucket_count = x.bucket_count();
|
||||
int count = 0;
|
||||
typename T::const_iterator pos = x.cbegin();
|
||||
|
||||
for(typename test::random_values<T>::const_iterator
|
||||
it = boost::next(this->values.begin(), x.size()), end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
strong.store(x);
|
||||
pos = x.insert(pos, *it);
|
||||
}
|
||||
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
BOOST_REQUIRE(x.bucket_count() != bucket_count);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
{
|
||||
typedef typename insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
typename T::size_type bucket_count = x.bucket_count();
|
||||
int count = 0;
|
||||
|
||||
for(typename test::random_values<T>::const_iterator
|
||||
it = boost::next(this->values.begin(), x.size()), end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
strong.store(x);
|
||||
x.insert(*it);
|
||||
}
|
||||
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
BOOST_REQUIRE(x.bucket_count() != bucket_count);
|
||||
}
|
||||
};
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(insert_test1)(insert_test2)(insert_test3)(insert_test4)
|
||||
(insert_test_rehash1)(insert_test_rehash2),
|
||||
CONTAINER_SEQ)
|
||||
80
test/exception/rehash_tests.cpp
Normal file
80
test/exception/rehash_tests.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to 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"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/exception_safety.hpp>
|
||||
#include <string>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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), 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(T const& x, strong_type const& strong) const {
|
||||
std::string scope(test::scope);
|
||||
|
||||
if(scope.find_first_of("hash::operator()") == std::string::npos &&
|
||||
scope.find_first_of("equal_to::operator()") == std::string::npos)
|
||||
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); }
|
||||
};
|
||||
|
||||
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); }
|
||||
};
|
||||
|
||||
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); }
|
||||
};
|
||||
|
||||
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); }
|
||||
};
|
||||
|
||||
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); }
|
||||
};
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(rehash_test0)(rehash_test1)(rehash_test2)(rehash_test3)(rehash_test4),
|
||||
CONTAINER_SEQ)
|
||||
107
test/exception/swap_tests.cpp
Normal file
107
test/exception/swap_tests.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to 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"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/exception_safety.hpp>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
template <class T>
|
||||
struct self_swap_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
self_swap_base(int count = 0) : values(count) {}
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
void run(T& x) const { x.swap(x); }
|
||||
void check(T const& x) const {
|
||||
std::string scope(test::scope);
|
||||
|
||||
#if BOOST_UNORDERED_SWAP_METHOD != 2
|
||||
BOOST_CHECK(
|
||||
scope == "hash::operator(hash)" ||
|
||||
scope == "hash::operator=(hash)" ||
|
||||
scope == "equal_to::operator(equal_to)" ||
|
||||
scope == "equal_to::operator=(equal_to)");
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
swap_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
|
||||
: x_values(count1), y_values(count2),
|
||||
initial_x(x_values.begin(), x_values.end(), 0, typename T::hasher(tag1),
|
||||
typename T::key_equal(tag1), typename T::allocator_type(tag1)),
|
||||
initial_y(y_values.begin(), y_values.end(), 0, typename T::hasher(tag2),
|
||||
typename T::key_equal(tag2), typename T::allocator_type(tag2))
|
||||
{}
|
||||
|
||||
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) {}
|
||||
}
|
||||
void check(data_type const& d) const {
|
||||
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) {}
|
||||
};
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(self_swap_test1)(self_swap_test2)
|
||||
(swap_test1)(swap_test2)(swap_test3)(swap_test4),
|
||||
CONTAINER_SEQ)
|
||||
Reference in New Issue
Block a user