mirror of
https://github.com/boostorg/unordered.git
synced 2025-05-10 07:34:00 +00:00
Merged revisions 43922,43962,43966,43971,43981,43995-43996,44042,44046-44048,44057 via svnmerge from https://svn.boost.org/svn/boost/branches/unordered/trunk ........ r43922 | danieljames | 2008-03-29 14:55:59 +0000 (Sat, 29 Mar 2008) | 1 line Fix some typos in the reference documentation. ........ r43962 | danieljames | 2008-03-31 18:29:59 +0100 (Mon, 31 Mar 2008) | 1 line Add a name variable to the release script, so that I can have different release names in different branches. ........ r43966 | danieljames | 2008-03-31 18:43:16 +0100 (Mon, 31 Mar 2008) | 1 line Fix the image directory for standalone docs. ........ r43971 | danieljames | 2008-03-31 19:17:25 +0100 (Mon, 31 Mar 2008) | 1 line Fix the unordered stylesheet. ........ r43981 | danieljames | 2008-04-01 13:31:26 +0100 (Tue, 01 Apr 2008) | 2 lines Cast the pointer in the Visual C++ 6.5 _Charalloc method. ........ r43995 | danieljames | 2008-04-02 12:50:27 +0100 (Wed, 02 Apr 2008) | 1 line Try using the interprocess containers for testing. Compilation is a bit slower but hopefully I'll run into less cross-platform problems. ........ r43996 | danieljames | 2008-04-02 13:25:49 +0100 (Wed, 02 Apr 2008) | 1 line Revert my experiment with the interprocess containers. It didn't work out. ........ r44042 | danieljames | 2008-04-04 20:38:09 +0100 (Fri, 04 Apr 2008) | 1 line Make hash table data a member of hash table, instead of a base. ........ r44046 | danieljames | 2008-04-05 12:38:05 +0100 (Sat, 05 Apr 2008) | 1 line Remove rvalue_ref from Jamfile.v2 - I didn't mean to check it in. ........ r44047 | danieljames | 2008-04-05 12:39:38 +0100 (Sat, 05 Apr 2008) | 1 line New constructors with allocators. ........ r44048 | danieljames | 2008-04-05 12:58:11 +0100 (Sat, 05 Apr 2008) | 1 line Document the new constructors. ........ r44057 | danieljames | 2008-04-05 17:08:23 +0100 (Sat, 05 Apr 2008) | 1 line Fix some bugs in the exception testing code. ........ [SVN r44417]
244 lines
6.8 KiB
C++
244 lines
6.8 KiB
C++
|
|
// Copyright 2006-2008 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_UNORDERED_EXCEPTION_TEST_HEADER)
|
|
#define BOOST_UNORDERED_EXCEPTION_TEST_HEADER
|
|
|
|
#include "./test.hpp"
|
|
|
|
#if defined(BOOST_UNORDERED_USE_TEST)
|
|
# define BOOST_TEST_MAIN
|
|
# include <boost/test/exception_safety.hpp>
|
|
# include <boost/test/unit_test.hpp>
|
|
#endif
|
|
|
|
#include <boost/preprocessor/seq/for_each_product.hpp>
|
|
#include <boost/preprocessor/seq/elem.hpp>
|
|
#include <boost/preprocessor/cat.hpp>
|
|
|
|
#if defined(BOOST_UNORDERED_USE_TEST)
|
|
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
|
|
UNORDERED_AUTO_TEST(name) \
|
|
{ \
|
|
test_func< type > fixture; \
|
|
::test::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
|
|
}
|
|
# define UNORDERED_EPOINT_IMPL BOOST_ITEST_EPOINT
|
|
#else
|
|
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
|
|
UNORDERED_AUTO_TEST(name) \
|
|
{ \
|
|
test_func< type > fixture; \
|
|
::test::lightweight::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
|
|
}
|
|
# define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
|
|
#endif
|
|
|
|
#define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()
|
|
|
|
#define RUN_EXCEPTION_TESTS(test_seq, param_seq) \
|
|
BOOST_PP_SEQ_FOR_EACH_PRODUCT(RUN_EXCEPTION_TESTS_OP, (test_seq)(param_seq)) \
|
|
RUN_TESTS()
|
|
|
|
#define RUN_EXCEPTION_TESTS_OP(r, product) \
|
|
UNORDERED_EXCEPTION_TEST_CASE( \
|
|
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \
|
|
BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(1, product)) \
|
|
), \
|
|
BOOST_PP_SEQ_ELEM(0, product), \
|
|
BOOST_PP_SEQ_ELEM(1, product) \
|
|
)
|
|
|
|
#define UNORDERED_SCOPE(scope_name) \
|
|
for(::test::scope_guard unordered_test_guard( \
|
|
BOOST_STRINGIZE(scope_name)); \
|
|
!unordered_test_guard.dismissed(); \
|
|
unordered_test_guard.dismiss())
|
|
|
|
#define UNORDERED_EPOINT(name) \
|
|
if(::test::exceptions_enabled) { \
|
|
UNORDERED_EPOINT_IMPL(name); \
|
|
}
|
|
|
|
#define ENABLE_EXCEPTIONS \
|
|
::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(true)
|
|
#define DISABLE_EXCEPTIONS \
|
|
::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false)
|
|
|
|
namespace test {
|
|
static char const* scope = "";
|
|
bool exceptions_enabled = false;
|
|
|
|
class scope_guard {
|
|
scope_guard& operator=(scope_guard const&);
|
|
scope_guard(scope_guard const&);
|
|
|
|
char const* old_scope_;
|
|
char const* scope_;
|
|
bool dismissed_;
|
|
public:
|
|
scope_guard(char const* name)
|
|
: old_scope_(scope),
|
|
scope_(name),
|
|
dismissed_(false)
|
|
{
|
|
scope = scope_;
|
|
}
|
|
|
|
~scope_guard() {
|
|
if(dismissed_) scope = old_scope_;
|
|
}
|
|
|
|
void dismiss() {
|
|
dismissed_ = true;
|
|
}
|
|
|
|
bool dismissed() const {
|
|
return dismissed_;
|
|
}
|
|
};
|
|
|
|
class exceptions_enable
|
|
{
|
|
exceptions_enable& operator=(exceptions_enable const&);
|
|
exceptions_enable(exceptions_enable const&);
|
|
|
|
bool old_value_;
|
|
public:
|
|
exceptions_enable(bool enable)
|
|
: old_value_(exceptions_enabled)
|
|
{
|
|
exceptions_enabled = enable;
|
|
}
|
|
|
|
~exceptions_enable()
|
|
{
|
|
exceptions_enabled = old_value_;
|
|
}
|
|
};
|
|
|
|
struct exception_base {
|
|
struct data_type {};
|
|
struct strong_type {
|
|
template <class T> void store(T const&) {}
|
|
template <class T> void test(T const&) const {}
|
|
};
|
|
data_type init() const { return data_type(); }
|
|
void check() const {}
|
|
};
|
|
|
|
template <class T, class P1, class P2, class T2>
|
|
inline void call_ignore_extra_parameters(void (T::*fn)() const, T2 const& obj,
|
|
P1&, P2&)
|
|
{
|
|
(obj.*fn)();
|
|
}
|
|
|
|
template <class T, class P1, class P2, class T2>
|
|
inline void call_ignore_extra_parameters(void (T::*fn)(P1&) const, T2 const& obj,
|
|
P1& p1, P2&)
|
|
{
|
|
(obj.*fn)(p1);
|
|
}
|
|
|
|
template <class T, class P1, class P2, class T2>
|
|
inline void call_ignore_extra_parameters(void (T::*fn)(P1&, P2&) const, T2 const& obj,
|
|
P1& p1, P2& p2)
|
|
{
|
|
(obj.*fn)(p1, p2);
|
|
}
|
|
|
|
template <class T>
|
|
T const& constant(T const& x) {
|
|
return x;
|
|
}
|
|
|
|
template <class Test>
|
|
class test_runner
|
|
{
|
|
Test const& test_;
|
|
public:
|
|
test_runner(Test const& t) : test_(t) {}
|
|
void operator()() const {
|
|
DISABLE_EXCEPTIONS;
|
|
test::scope = "";
|
|
BOOST_DEDUCED_TYPENAME Test::data_type x(test_.init());
|
|
BOOST_DEDUCED_TYPENAME Test::strong_type strong;
|
|
strong.store(x);
|
|
try {
|
|
ENABLE_EXCEPTIONS;
|
|
call_ignore_extra_parameters<Test, BOOST_DEDUCED_TYPENAME Test::data_type, BOOST_DEDUCED_TYPENAME Test::strong_type>(&Test::run, test_, x, strong);
|
|
}
|
|
catch(...) {
|
|
call_ignore_extra_parameters<Test, BOOST_DEDUCED_TYPENAME Test::data_type const, BOOST_DEDUCED_TYPENAME Test::strong_type const>(&Test::check, test_,
|
|
constant(x), constant(strong));
|
|
throw;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
|
|
#if defined(BOOST_UNORDERED_USE_TEST)
|
|
template <class Test>
|
|
void exception_safety(Test const& f, char const* name) {
|
|
test_runner<Test> runner(f);
|
|
::boost::itest::exception_safety(runner, name);
|
|
}
|
|
#else
|
|
// Quick exception testing based on lightweight test
|
|
|
|
namespace lightweight {
|
|
static int iteration;
|
|
static int count;
|
|
|
|
struct test_exception {
|
|
char const* name;
|
|
test_exception(char const* n) : name(n) {}
|
|
};
|
|
|
|
struct test_failure {
|
|
};
|
|
|
|
void epoint(char const* name) {
|
|
++count;
|
|
if(count == iteration) {
|
|
throw test_exception(name);
|
|
}
|
|
}
|
|
|
|
template <class Test>
|
|
void exception_safety(Test const& f, char const* name) {
|
|
test_runner<Test> runner(f);
|
|
|
|
iteration = 0;
|
|
bool success = false;
|
|
do {
|
|
++iteration;
|
|
count = 0;
|
|
|
|
try {
|
|
runner();
|
|
success = true;
|
|
}
|
|
catch(test_failure) {
|
|
BOOST_ERROR("test_failure caught.");
|
|
break;
|
|
}
|
|
catch(test_exception) {
|
|
continue;
|
|
}
|
|
catch(...) {
|
|
BOOST_ERROR("Unexpected exception.");
|
|
break;
|
|
}
|
|
} while(!success);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#endif
|