2 // Copyright 2006-2009 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #if !defined(BOOST_UNORDERED_EXCEPTION_TEST_HEADER)
7 #define BOOST_UNORDERED_EXCEPTION_TEST_HEADER
11 #include <boost/preprocessor/seq/for_each_product.hpp>
12 #include <boost/preprocessor/seq/elem.hpp>
13 #include <boost/preprocessor/cat.hpp>
15 # define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
16 UNORDERED_AUTO_TEST(name) \
18 test_func< type > fixture; \
19 ::test::lightweight::exception_safety( \
20 fixture, BOOST_STRINGIZE(test_func<type>)); \
23 # define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
25 #define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()
27 #define RUN_EXCEPTION_TESTS(test_seq, param_seq) \
28 BOOST_PP_SEQ_FOR_EACH_PRODUCT(RUN_EXCEPTION_TESTS_OP, \
29 (test_seq)(param_seq)) \
32 #define RUN_EXCEPTION_TESTS_OP(r, product) \
33 UNORDERED_EXCEPTION_TEST_CASE( \
34 BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \
35 BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(1, product)) \
37 BOOST_PP_SEQ_ELEM(0, product), \
38 BOOST_PP_SEQ_ELEM(1, product) \
41 #define UNORDERED_SCOPE(scope_name) \
42 for(::test::scope_guard unordered_test_guard( \
43 BOOST_STRINGIZE(scope_name)); \
44 !unordered_test_guard.dismissed(); \
45 unordered_test_guard.dismiss()) \
47 #define UNORDERED_EPOINT(name) \
48 if(::test::exceptions_enabled) { \
49 UNORDERED_EPOINT_IMPL(name); \
52 #define ENABLE_EXCEPTIONS \
53 ::test::exceptions_enable BOOST_PP_CAT( \
54 ENABLE_EXCEPTIONS_, __LINE__)(true) \
56 #define DISABLE_EXCEPTIONS \
57 ::test::exceptions_enable BOOST_PP_CAT( \
58 ENABLE_EXCEPTIONS_, __LINE__)(false) \
61 static char const* scope = "";
62 bool exceptions_enabled = false;
65 scope_guard& operator=(scope_guard const&);
66 scope_guard(scope_guard const&);
68 char const* old_scope_;
72 scope_guard(char const* name)
81 if(dismissed_) scope = old_scope_;
88 bool dismissed() const {
93 class exceptions_enable
95 exceptions_enable& operator=(exceptions_enable const&);
96 exceptions_enable(exceptions_enable const&);
100 exceptions_enable(bool enable)
101 : old_value_(exceptions_enabled)
103 exceptions_enabled = enable;
108 exceptions_enabled = old_value_;
112 struct exception_base {
115 template <class T> void store(T const&) {}
116 template <class T> void test(T const&) const {}
118 data_type init() const { return data_type(); }
119 void check BOOST_PREVENT_MACRO_SUBSTITUTION() const {}
122 template <class T, class P1, class P2, class T2>
123 inline void call_ignore_extra_parameters(
124 void (T::*fn)() const, T2 const& obj,
130 template <class T, class P1, class P2, class T2>
131 inline void call_ignore_extra_parameters(
132 void (T::*fn)(P1&) const, T2 const& obj,
138 template <class T, class P1, class P2, class T2>
139 inline void call_ignore_extra_parameters(
140 void (T::*fn)(P1&, P2&) const, T2 const& obj,
147 T const& constant(T const& x) {
151 template <class Test>
156 test_runner(test_runner const&);
157 test_runner& operator=(test_runner const&);
159 test_runner(Test const& t) : test_(t) {}
160 void operator()() const {
163 BOOST_DEDUCED_TYPENAME Test::data_type x(test_.init());
164 BOOST_DEDUCED_TYPENAME Test::strong_type strong;
168 call_ignore_extra_parameters<
170 BOOST_DEDUCED_TYPENAME Test::data_type,
171 BOOST_DEDUCED_TYPENAME Test::strong_type
172 >(&Test::run, test_, x, strong);
175 call_ignore_extra_parameters<
177 BOOST_DEDUCED_TYPENAME Test::data_type const,
178 BOOST_DEDUCED_TYPENAME Test::strong_type const
179 >(&Test::check, test_, constant(x), constant(strong));
185 // Quick exception testing based on lightweight test
187 namespace lightweight {
188 static int iteration;
191 struct test_exception {
193 test_exception(char const* n) : name(n) {}
196 struct test_failure {
199 void epoint(char const* name) {
201 if(count == iteration) {
202 throw test_exception(name);
206 template <class Test>
207 void exception_safety(Test const& f, char const* /*name*/) {
208 test_runner<Test> runner(f);
211 bool success = false;
220 catch(test_failure) {
221 BOOST_ERROR("test_failure caught.");
224 catch(test_exception) {
228 BOOST_ERROR("Unexpected exception.");