mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
Fix exception handling in rehash_impl
And improve tests so they will catch the error, and other similar errors.
This commit is contained in:
@ -1516,7 +1516,7 @@ construct_from_args(Alloc& alloc, std::pair<A, B>* address, BOOST_FWD_REF(A0),
|
||||
{
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(address->first));
|
||||
BOOST_RETHROW;
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
@ -1551,7 +1551,7 @@ inline typename enable_if<use_piecewise<A0>, void>::type construct_from_args(
|
||||
{
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(address->first));
|
||||
BOOST_RETHROW;
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
@ -1630,7 +1630,7 @@ inline void construct_from_args(Alloc& alloc, std::pair<A, B>* address,
|
||||
{
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(address->first));
|
||||
BOOST_RETHROW;
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
@ -1841,7 +1841,7 @@ construct_node_pair(Alloc& alloc, BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(a.node_->value_ptr()->first));
|
||||
BOOST_RETHROW;
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return a.release();
|
||||
@ -1865,7 +1865,7 @@ construct_node_pair(Alloc& alloc, BOOST_FWD_REF(Key) k, BOOST_FWD_REF(Mapped) m)
|
||||
{
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(a.node_->value_ptr()->first));
|
||||
BOOST_RETHROW;
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return a.release();
|
||||
@ -1890,7 +1890,7 @@ construct_node_pair_from_args(
|
||||
{
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(a.node_->value_ptr()->first));
|
||||
BOOST_RETHROW;
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return a.release();
|
||||
@ -4274,7 +4274,10 @@ inline void table<Types>::rehash_impl(std::size_t num_buckets)
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...) { delete_nodes(prev, node_pointer()); }
|
||||
BOOST_CATCH(...) {
|
||||
delete_nodes(prev, node_pointer());
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#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
|
||||
@ -21,7 +22,13 @@ template <class T> struct self_assign_base : public test::exception_base
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
void run(T& x) const { x = x; }
|
||||
|
||||
void run(T& x) const {
|
||||
x = x;
|
||||
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);
|
||||
@ -57,7 +64,13 @@ template <class T> struct assign_base : public test::exception_base
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(x); }
|
||||
void run(T& x1) const { x1 = y; }
|
||||
|
||||
void run(T& x1) const {
|
||||
x1 = y;
|
||||
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);
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include "../helpers/input_iterator.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
|
||||
template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
@ -25,7 +27,8 @@ template <class T> struct construct_test1 : public objects, test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T x;
|
||||
avoid_unused_warning(x);
|
||||
BOOST_TEST(x.empty());
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -34,7 +37,8 @@ template <class T> struct construct_test2 : public objects, test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T x(300);
|
||||
avoid_unused_warning(x);
|
||||
BOOST_TEST(x.empty());
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -43,7 +47,8 @@ template <class T> struct construct_test3 : public objects, test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T x(0, hash);
|
||||
avoid_unused_warning(x);
|
||||
BOOST_TEST(x.empty());
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -52,7 +57,8 @@ template <class T> struct construct_test4 : public objects, test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T x(0, hash, equal_to);
|
||||
avoid_unused_warning(x);
|
||||
BOOST_TEST(x.empty());
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,7 +67,8 @@ template <class T> struct construct_test5 : public objects, test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T x(50, hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
BOOST_TEST(x.empty());
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -70,7 +77,8 @@ template <class T> struct construct_test6 : public objects, test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T x(allocator);
|
||||
avoid_unused_warning(x);
|
||||
BOOST_TEST(x.empty());
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -87,7 +95,8 @@ template <class T> struct range_construct_test1 : public range<T>, objects
|
||||
void run() const
|
||||
{
|
||||
T x(this->values.begin(), this->values.end());
|
||||
avoid_unused_warning(x);
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -96,7 +105,8 @@ template <class T> struct range_construct_test2 : public range<T>, objects
|
||||
void run() const
|
||||
{
|
||||
T x(this->values.begin(), this->values.end(), 0);
|
||||
avoid_unused_warning(x);
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -105,7 +115,8 @@ template <class T> struct range_construct_test3 : public range<T>, objects
|
||||
void run() const
|
||||
{
|
||||
T x(this->values.begin(), this->values.end(), 0, hash);
|
||||
avoid_unused_warning(x);
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -114,7 +125,8 @@ 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);
|
||||
avoid_unused_warning(x);
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -128,7 +140,8 @@ template <class T> struct range_construct_test5 : public range<T>, objects
|
||||
{
|
||||
T x(this->values.begin(), this->values.end(), 0, hash, equal_to,
|
||||
allocator);
|
||||
avoid_unused_warning(x);
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -143,7 +156,8 @@ template <class T> struct input_range_construct_test : public range<T>, objects
|
||||
end = this->values.end();
|
||||
T x(test::input_iterator(begin), test::input_iterator(end), 0, hash,
|
||||
equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -156,7 +170,8 @@ template <class T> struct copy_range_construct_test : public range<T>, objects
|
||||
T x(test::copy_iterator(this->values.begin()),
|
||||
test::copy_iterator(this->values.end()), 0, hash, equal_to,
|
||||
allocator);
|
||||
avoid_unused_warning(x);
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
|
||||
template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
@ -18,7 +20,8 @@ template <class T> struct copy_test1 : public test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
BOOST_TEST(y.empty());
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
};
|
||||
|
||||
@ -32,7 +35,8 @@ template <class T> struct copy_test2 : public test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
test::check_container(y, this->values);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
};
|
||||
|
||||
@ -46,7 +50,8 @@ template <class T> struct copy_test3 : public test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
test::check_container(y, this->values);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,7 +66,8 @@ template <class T> struct copy_with_allocator_test : public test::exception_base
|
||||
void run() const
|
||||
{
|
||||
T y(x, allocator);
|
||||
avoid_unused_warning(y);
|
||||
test::check_container(y, this->values);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -43,6 +43,9 @@ template <class T> struct erase_by_key_test1 : public erase_test_base<T>
|
||||
it != end; ++it) {
|
||||
x.erase(test::get_key<T>(*it));
|
||||
}
|
||||
|
||||
BOOST_TEST(x.empty());
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,13 +2,14 @@
|
||||
// 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 <iostream>
|
||||
|
||||
#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>
|
||||
|
||||
@ -54,6 +55,10 @@ template <class T> struct emplace_test1 : public insert_test_base<T>
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.emplace(*it);
|
||||
}
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -72,6 +77,10 @@ template <class T> struct insert_test1 : public insert_test_base<T>
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(*it);
|
||||
}
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -88,12 +97,23 @@ template <class T> struct insert_test2 : public insert_test_base<T>
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(x.begin(), *it);
|
||||
}
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct insert_test3 : public insert_test_base<T>
|
||||
{
|
||||
void run(T& x) const { x.insert(this->values.begin(), this->values.end()); }
|
||||
void run(T& x) const
|
||||
{
|
||||
x.insert(this->values.begin(), this->values.end());
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
|
||||
{
|
||||
@ -114,6 +134,10 @@ template <class T> struct insert_test4 : public insert_test_base<T>
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(it, test::next(it));
|
||||
}
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -147,17 +171,30 @@ template <class T> struct insert_test_rehash1 : public insert_test_base<T>
|
||||
int count = 0;
|
||||
BOOST_DEDUCED_TYPENAME T::const_iterator pos = x.cbegin();
|
||||
|
||||
test::list<typename T::value_type> v;
|
||||
{
|
||||
DISABLE_EXCEPTIONS;
|
||||
v.insert(x.begin(), x.end());
|
||||
}
|
||||
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
pos = x.insert(pos, *it);
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
v.push_back(*it);
|
||||
}
|
||||
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
BOOST_TEST(x.bucket_count() != bucket_count);
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -170,17 +207,30 @@ template <class T> struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
|
||||
int count = 0;
|
||||
|
||||
test::list<typename T::value_type> v;
|
||||
{
|
||||
DISABLE_EXCEPTIONS;
|
||||
v.insert(x.begin(), x.end());
|
||||
}
|
||||
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(*it);
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
v.push_back(*it);
|
||||
}
|
||||
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
BOOST_TEST(x.bucket_count() != bucket_count);
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -218,6 +268,14 @@ template <class T> struct insert_test_rehash3 : public insert_test_base<T>
|
||||
void run(T& x) const
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
|
||||
test::list<typename T::value_type> v;
|
||||
|
||||
{
|
||||
DISABLE_EXCEPTIONS;
|
||||
v.insert(x.begin(), x.end());
|
||||
v.insert(test::next(this->values.begin(), x.size()),
|
||||
test::next(this->values.begin(), x.size() + 20));
|
||||
}
|
||||
|
||||
x.insert(test::next(this->values.begin(), x.size()),
|
||||
test::next(this->values.begin(), x.size() + 20));
|
||||
@ -225,6 +283,10 @@ template <class T> struct insert_test_rehash3 : public insert_test_base<T>
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
BOOST_TEST(x.bucket_count() != bucket_count);
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, v);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
|
||||
@ -263,6 +325,10 @@ template <class T> struct pair_emplace_test1 : public insert_test_base<T>
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(it->first), boost::make_tuple(it->second));
|
||||
}
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
@ -281,6 +347,10 @@ template <class T> struct pair_emplace_test2 : public insert_test_base<T>
|
||||
boost::make_tuple(it->first),
|
||||
boost::make_tuple(it->second.tag1_, it->second.tag2_));
|
||||
}
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
@ -42,7 +43,11 @@ template <class T> struct move_assign_base : public test::exception_base
|
||||
T y1 = y;
|
||||
disable_exceptions.release();
|
||||
x1 = boost::move(y1);
|
||||
|
||||
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);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
#include <string>
|
||||
|
||||
#include <iostream>
|
||||
@ -49,34 +50,76 @@ template <class T> struct rehash_test_base : public test::exception_base
|
||||
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); }
|
||||
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); }
|
||||
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); }
|
||||
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); }
|
||||
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); }
|
||||
void run(T& x) const
|
||||
{
|
||||
x.rehash(0);
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x, this->values);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(rehash_test0)(rehash_test1)(rehash_test2)(rehash_test3)(rehash_test4),
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS((rehash_test0)(rehash_test1)(rehash_test2)(rehash_test3)(
|
||||
rehash_test4)(rehash_test5),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#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
|
||||
@ -21,7 +22,15 @@ template <class T> struct self_swap_base : public test::exception_base
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
void run(T& x) const { x.swap(x); }
|
||||
|
||||
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);
|
||||
@ -82,7 +91,14 @@ template <class T> struct swap_base : public test::exception_base
|
||||
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);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "../helpers/count.hpp"
|
||||
#include "../helpers/fwd.hpp"
|
||||
#include "../helpers/memory.hpp"
|
||||
#include "../objects/fwd.hpp"
|
||||
#include <boost/limits.hpp>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
@ -311,6 +312,55 @@ class equal_to
|
||||
}
|
||||
};
|
||||
|
||||
class less
|
||||
{
|
||||
int tag_;
|
||||
|
||||
public:
|
||||
less(int t = 0) : tag_(t) {}
|
||||
|
||||
less(less const& x) : tag_(x.tag_) {}
|
||||
|
||||
bool operator()(object const& x1, object const& x2) const
|
||||
{
|
||||
return less_impl(x1, x2);
|
||||
}
|
||||
|
||||
bool operator()(std::pair<object, object> const& x1,
|
||||
std::pair<object, object> const& x2) const
|
||||
{
|
||||
if (less_impl(x1.first, x2.first)) {
|
||||
return true;
|
||||
}
|
||||
if (!less_impl(x1.first, x2.first)) {
|
||||
return false;
|
||||
}
|
||||
return less_impl(x1.second, x2.second);
|
||||
}
|
||||
|
||||
bool less_impl(object const& x1, object const& x2) const
|
||||
{
|
||||
switch (tag_) {
|
||||
case 1:
|
||||
return x1.tag1_ < x2.tag1_;
|
||||
case 2:
|
||||
return x1.tag2_ < x2.tag2_;
|
||||
default:
|
||||
return x1 < x2;
|
||||
}
|
||||
}
|
||||
|
||||
friend bool operator==(less const& x1, less const& x2)
|
||||
{
|
||||
return x1.tag_ == x2.tag_;
|
||||
}
|
||||
|
||||
friend bool operator!=(less const& x1, less const& x2)
|
||||
{
|
||||
return x1.tag_ != x2.tag_;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> class allocator
|
||||
{
|
||||
public:
|
||||
@ -672,6 +722,14 @@ inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y)
|
||||
}
|
||||
}
|
||||
|
||||
namespace test {
|
||||
template <typename X> struct equals_to_compare;
|
||||
template <> struct equals_to_compare<test::exception::equal_to>
|
||||
{
|
||||
typedef test::exception::less type;
|
||||
};
|
||||
}
|
||||
|
||||
// Workaround for ADL deficient compilers
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
namespace test {
|
||||
|
Reference in New Issue
Block a user