| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 20:56:23 +00:00
										 |  |  | // Copyright 2006-2009 Daniel James.
 | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | // 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-01 18:35:50 +00:00
										 |  |  | #include "./count.hpp"
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | #include "./test.hpp"
 | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <boost/preprocessor/cat.hpp>
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | #include <boost/preprocessor/seq/elem.hpp>
 | 
					
						
							|  |  |  | #include <boost/preprocessor/seq/for_each_product.hpp>
 | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | #define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type)                   \
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:34:47 +01:00
										 |  |  |   UNORDERED_AUTO_TEST (name) {                                                 \ | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     test_func<type> fixture;                                                   \ | 
					
						
							|  |  |  |     ::test::lightweight::exception_safety(                                     \ | 
					
						
							|  |  |  |       fixture, BOOST_STRINGIZE(test_func<type>));                              \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-21 00:20:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | #define UNORDERED_EXCEPTION_TEST_CASE_REPEAT(name, test_func, n, type)         \
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:34:47 +01:00
										 |  |  |   UNORDERED_AUTO_TEST (name) {                                                 \ | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     for (unsigned i = 0; i < n; ++i) {                                         \ | 
					
						
							|  |  |  |       test_func<type> fixture;                                                 \ | 
					
						
							|  |  |  |       ::test::lightweight::exception_safety(                                   \ | 
					
						
							|  |  |  |         fixture, BOOST_STRINGIZE(test_func<type>));                            \ | 
					
						
							|  |  |  |     }                                                                          \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-10-21 00:20:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | #define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
 | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-24 17:03:15 +00:00
										 |  |  | #define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | #define EXCEPTION_TESTS(test_seq, param_seq)                                   \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   BOOST_PP_SEQ_FOR_EACH_PRODUCT(EXCEPTION_TESTS_OP, (test_seq)((1))(param_seq)) | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define EXCEPTION_TESTS_REPEAT(n, test_seq, param_seq)                         \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   BOOST_PP_SEQ_FOR_EACH_PRODUCT(EXCEPTION_TESTS_OP, (test_seq)((n))(param_seq)) | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define EXCEPTION_TESTS_OP(r, product)                                         \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   UNORDERED_EXCEPTION_TEST_CASE_REPEAT(                                        \ | 
					
						
							|  |  |  |     BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product),                                \ | 
					
						
							|  |  |  |       BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(2, product))),                         \ | 
					
						
							|  |  |  |     BOOST_PP_SEQ_ELEM(0, product), BOOST_PP_SEQ_ELEM(1, product),              \ | 
					
						
							|  |  |  |     BOOST_PP_SEQ_ELEM(2, product)) | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define UNORDERED_SCOPE(scope_name)                                            \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   for (::test::scope_guard unordered_test_guard(BOOST_STRINGIZE(scope_name));  \ | 
					
						
							|  |  |  |        !unordered_test_guard.dismissed(); unordered_test_guard.dismiss()) | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define UNORDERED_EPOINT(name)                                                 \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   if (::test::exceptions_enabled) {                                            \ | 
					
						
							|  |  |  |     UNORDERED_EPOINT_IMPL(name);                                               \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define ENABLE_EXCEPTIONS                                                      \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(true) | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define DISABLE_EXCEPTIONS                                                     \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false) | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace test { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   static char const* scope = ""; | 
					
						
							|  |  |  |   bool exceptions_enabled = false; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   class scope_guard | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     scope_guard& operator=(scope_guard const&); | 
					
						
							|  |  |  |     scope_guard(scope_guard const&); | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     char const* old_scope_; | 
					
						
							|  |  |  |     char const* scope_; | 
					
						
							|  |  |  |     bool dismissed_; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |   public: | 
					
						
							|  |  |  |     scope_guard(char const* name) | 
					
						
							|  |  |  |         : old_scope_(scope), scope_(name), dismissed_(false) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       scope = scope_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     ~scope_guard() | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (dismissed_) | 
					
						
							|  |  |  |         scope = old_scope_; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void dismiss() { dismissed_ = true; } | 
					
						
							| 
									
										
										
										
											2016-10-02 13:04:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     bool dismissed() const { return dismissed_; } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   class exceptions_enable | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     exceptions_enable& operator=(exceptions_enable const&); | 
					
						
							|  |  |  |     exceptions_enable(exceptions_enable const&); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool old_value_; | 
					
						
							|  |  |  |     bool released_; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |   public: | 
					
						
							|  |  |  |     exceptions_enable(bool enable) | 
					
						
							|  |  |  |         : old_value_(exceptions_enabled), released_(false) | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       exceptions_enabled = enable; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     ~exceptions_enable() | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (!released_) { | 
					
						
							|  |  |  |         exceptions_enabled = old_value_; | 
					
						
							|  |  |  |         released_ = true; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void release() | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (!released_) { | 
					
						
							|  |  |  |         exceptions_enabled = old_value_; | 
					
						
							|  |  |  |         released_ = true; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   struct exception_base | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     struct data_type | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     struct strong_type | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       template <class T> void store(T const&) {} | 
					
						
							|  |  |  |       template <class T> void test(T const&) const {} | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  |     data_type init() const { return data_type(); } | 
					
						
							|  |  |  |     void check BOOST_PREVENT_MACRO_SUBSTITUTION() const {} | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <class T, class P1, class P2, class T2> | 
					
						
							|  |  |  |   inline void call_ignore_extra_parameters( | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void (T::*fn)() const, T2 const& obj, P1&, P2&) | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     (obj.*fn)(); | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <class T, class P1, class P2, class T2> | 
					
						
							|  |  |  |   inline void call_ignore_extra_parameters( | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void (T::*fn)(P1&) const, T2 const& obj, P1& p1, P2&) | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     (obj.*fn)(p1); | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <class T, class P1, class P2, class T2> | 
					
						
							|  |  |  |   inline void call_ignore_extra_parameters( | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     void (T::*fn)(P1&, P2&) const, T2 const& obj, P1& p1, P2& p2) | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     (obj.*fn)(p1, p2); | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <class T> T const& constant(T const& x) { return x; } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   template <class Test> class test_runner | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     Test const& test_; | 
					
						
							|  |  |  |     bool exception_in_check_; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     test_runner(test_runner const&); | 
					
						
							|  |  |  |     test_runner& operator=(test_runner const&); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     test_runner(Test const& t) : test_(t), exception_in_check_(false) {} | 
					
						
							|  |  |  |     void run() | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       DISABLE_EXCEPTIONS; | 
					
						
							|  |  |  |       test::check_instances check; | 
					
						
							|  |  |  |       test::scope = ""; | 
					
						
							| 
									
										
										
										
											2018-01-27 09:39:59 +00:00
										 |  |  |       typename Test::data_type x(test_.init()); | 
					
						
							|  |  |  |       typename Test::strong_type strong; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       strong.store(x); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         ENABLE_EXCEPTIONS; | 
					
						
							| 
									
										
										
										
											2018-01-27 09:39:59 +00:00
										 |  |  |         call_ignore_extra_parameters<Test, typename Test::data_type, | 
					
						
							|  |  |  |           typename Test::strong_type>(&Test::run, test_, x, strong); | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } catch (...) { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         try { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           DISABLE_EXCEPTIONS; | 
					
						
							| 
									
										
										
										
											2018-01-27 09:39:59 +00:00
										 |  |  |           call_ignore_extra_parameters<Test, typename Test::data_type const, | 
					
						
							|  |  |  |             typename Test::strong_type const>( | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |             &Test::check, test_, constant(x), constant(strong)); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         } catch (...) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           exception_in_check_ = true; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |         throw; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     void end() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (exception_in_check_) { | 
					
						
							|  |  |  |         BOOST_ERROR("Unexcpected exception in test_runner check call."); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   // Quick exception testing based on lightweight test
 | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   namespace lightweight { | 
					
						
							|  |  |  |     static int iteration; | 
					
						
							|  |  |  |     static int count; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     struct test_exception | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       char const* name; | 
					
						
							|  |  |  |       test_exception(char const* n) : name(n) {} | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     struct test_failure | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     void epoint(char const* name) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ++count; | 
					
						
							|  |  |  |       if (count == iteration) { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         throw test_exception(name); | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     template <class Test> | 
					
						
							|  |  |  |     void exception_safety(Test const& f, char const* /*name*/) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       test_runner<Test> runner(f); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       iteration = 0; | 
					
						
							|  |  |  |       bool success = false; | 
					
						
							|  |  |  |       unsigned int failure_count = 0; | 
					
						
							|  |  |  |       char const* error_msg = 0; | 
					
						
							|  |  |  |       do { | 
					
						
							| 
									
										
										
										
											2017-04-25 01:10:53 +01:00
										 |  |  |         int error_count = boost::detail::test_errors(); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         ++iteration; | 
					
						
							|  |  |  |         count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           runner.run(); | 
					
						
							|  |  |  |           success = true; | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         } catch (test_failure) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           error_msg = "test_failure caught."; | 
					
						
							|  |  |  |           break; | 
					
						
							| 
									
										
										
										
											2017-04-25 01:11:18 +01:00
										 |  |  |         } catch (test_exception e) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           if (error_count != boost::detail::test_errors()) { | 
					
						
							|  |  |  |             BOOST_LIGHTWEIGHT_TEST_OSTREAM | 
					
						
							|  |  |  |               << "Iteration: " << iteration | 
					
						
							|  |  |  |               << " Error found for epoint: " << e.name << std::endl; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         } catch (...) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           error_msg = "Unexpected exception."; | 
					
						
							|  |  |  |           break; | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-04-25 01:10:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (error_count != boost::detail::test_errors()) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           ++failure_count; | 
					
						
							| 
									
										
										
										
											2017-04-25 01:10:53 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } while (!success && failure_count < 5); | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       if (error_msg) { | 
					
						
							| 
									
										
										
										
											2017-02-19 13:05:17 +00:00
										 |  |  |         BOOST_ERROR(error_msg); | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |       runner.end(); | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     //
 | 
					
						
							|  |  |  |     // An alternative way to run exception tests.
 | 
					
						
							|  |  |  |     // See merge_exception_tests.cpp for an example.
 | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |     struct exception_looper | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       bool success; | 
					
						
							|  |  |  |       unsigned int failure_count; | 
					
						
							|  |  |  |       char const* error_msg; | 
					
						
							|  |  |  |       int error_count; | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       exception_looper() : success(false), failure_count(0), error_msg(0) {} | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       void start() { iteration = 0; } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       bool loop_condition() const | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |         return !error_msg && !success && failure_count < 5; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       void start_iteration() | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |         error_count = boost::detail::test_errors(); | 
					
						
							|  |  |  |         ++iteration; | 
					
						
							|  |  |  |         count = 0; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       void successful_run() { success = true; } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       void test_failure_caught(test_failure const&) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |         error_msg = "test_failure caught."; | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       void test_exception_caught(test_exception const& e) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |         if (error_count != boost::detail::test_errors()) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           BOOST_LIGHTWEIGHT_TEST_OSTREAM | 
					
						
							|  |  |  |             << "Iteration: " << iteration | 
					
						
							|  |  |  |             << " Error found for epoint: " << e.name << std::endl; | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       void unexpected_exception_caught() | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         error_msg = "Unexpected exception."; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       void end() | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |         if (error_msg) { | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |           BOOST_ERROR(error_msg); | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define EXCEPTION_LOOP(op)                                                     \
 | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   test::lightweight::exception_looper looper;                                  \ | 
					
						
							|  |  |  |   looper.start();                                                              \ | 
					
						
							|  |  |  |   while (looper.loop_condition()) {                                            \ | 
					
						
							|  |  |  |     looper.start_iteration();                                                  \ | 
					
						
							|  |  |  |     try {                                                                      \ | 
					
						
							|  |  |  |       op;                                                                      \ | 
					
						
							|  |  |  |       looper.successful_run();                                                 \ | 
					
						
							|  |  |  |     } catch (test::lightweight::test_failure e) {                              \ | 
					
						
							|  |  |  |       looper.test_failure_caught(e);                                           \ | 
					
						
							|  |  |  |     } catch (test::lightweight::test_exception e) {                            \ | 
					
						
							|  |  |  |       looper.test_exception_caught(e);                                         \ | 
					
						
							|  |  |  |     } catch (...) {                                                            \ | 
					
						
							|  |  |  |       looper.unexpected_exception_caught();                                    \ | 
					
						
							| 
									
										
										
										
											2017-05-07 17:54:34 +01:00
										 |  |  |     }                                                                          \ | 
					
						
							| 
									
										
										
										
											2017-06-11 20:55:59 +01:00
										 |  |  |   }                                                                            \ | 
					
						
							|  |  |  |   looper.end(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-01-13 16:19:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |