1 | #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP |
2 | #define BOOST_CORE_LIGHTWEIGHT_TEST_HPP |
3 | |
4 | // MS compatible compilers support #pragma once |
5 | |
6 | #if defined(_MSC_VER) |
7 | # pragma once |
8 | #endif |
9 | |
10 | // |
11 | // boost/core/lightweight_test.hpp - lightweight test library |
12 | // |
13 | // Copyright (c) 2002, 2009, 2014 Peter Dimov |
14 | // Copyright (2) Beman Dawes 2010, 2011 |
15 | // Copyright (3) Ion Gaztanaga 2013 |
16 | // |
17 | // Copyright 2018 Glen Joseph Fernandes |
18 | // (glenjofe@gmail.com) |
19 | // |
20 | // Distributed under the Boost Software License, Version 1.0. |
21 | // See accompanying file LICENSE_1_0.txt or copy at |
22 | // http://www.boost.org/LICENSE_1_0.txt |
23 | // |
24 | |
25 | #include <boost/core/detail/lwt_unattended.hpp> |
26 | #include <boost/current_function.hpp> |
27 | #include <boost/config.hpp> |
28 | #include <exception> |
29 | #include <iostream> |
30 | #include <iterator> |
31 | #include <string> |
32 | #include <cstdlib> |
33 | #include <cstring> |
34 | #include <cstddef> |
35 | #include <cctype> |
36 | |
37 | // IDE's like Visual Studio perform better if output goes to std::cout or |
38 | // some other stream, so allow user to configure output stream: |
39 | #ifndef BOOST_LIGHTWEIGHT_TEST_OSTREAM |
40 | # define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cerr |
41 | #endif |
42 | |
43 | namespace boost |
44 | { |
45 | namespace detail |
46 | { |
47 | |
48 | class test_result |
49 | { |
50 | public: |
51 | |
52 | test_result(): report_( false ), errors_( 0 ) |
53 | { |
54 | core::detail::lwt_unattended(); |
55 | } |
56 | |
57 | ~test_result() |
58 | { |
59 | if( !report_ ) |
60 | { |
61 | BOOST_LIGHTWEIGHT_TEST_OSTREAM << "main() should return report_errors()" << std::endl; |
62 | std::abort(); |
63 | } |
64 | } |
65 | |
66 | int& errors() |
67 | { |
68 | return errors_; |
69 | } |
70 | |
71 | void done() |
72 | { |
73 | report_ = true; |
74 | } |
75 | |
76 | private: |
77 | |
78 | bool report_; |
79 | int errors_; |
80 | }; |
81 | |
82 | inline test_result& test_results() |
83 | { |
84 | static test_result instance; |
85 | return instance; |
86 | } |
87 | |
88 | inline int& test_errors() |
89 | { |
90 | return test_results().errors(); |
91 | } |
92 | |
93 | inline bool test_impl(char const * expr, char const * file, int line, char const * function, bool v) |
94 | { |
95 | if( v ) |
96 | { |
97 | test_results(); |
98 | return true; |
99 | } |
100 | else |
101 | { |
102 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
103 | << file << "(" << line << "): test '" << expr << "' failed in function '" |
104 | << function << "'" << std::endl; |
105 | ++test_results().errors(); |
106 | return false; |
107 | } |
108 | } |
109 | |
110 | inline void error_impl(char const * msg, char const * file, int line, char const * function) |
111 | { |
112 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
113 | << file << "(" << line << "): " << msg << " in function '" |
114 | << function << "'" << std::endl; |
115 | ++test_results().errors(); |
116 | } |
117 | |
118 | inline void throw_failed_impl(const char* expr, char const * excep, char const * file, int line, char const * function) |
119 | { |
120 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
121 | << file << "(" << line << "): expression '" << expr << "' did not throw exception '" << excep << "' in function '" |
122 | << function << "'" << std::endl; |
123 | ++test_results().errors(); |
124 | } |
125 | |
126 | inline void no_throw_failed_impl(const char* expr, const char* file, int line, const char* function) |
127 | { |
128 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
129 | << file << "(" << line << "): expression '" << expr << "' threw an exception in function '" |
130 | << function << "'" << std::endl; |
131 | ++test_results().errors(); |
132 | } |
133 | |
134 | inline void no_throw_failed_impl(const char* expr, const char* what, const char* file, int line, const char* function) |
135 | { |
136 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
137 | << file << "(" << line << "): expression '" << expr << "' threw an exception in function '" |
138 | << function << "': " << what << std::endl; |
139 | ++test_results().errors(); |
140 | } |
141 | |
142 | // In the comparisons below, it is possible that T and U are signed and unsigned integer types, which generates warnings in some compilers. |
143 | // A cleaner fix would require common_type trait or some meta-programming, which would introduce a dependency on Boost.TypeTraits. To avoid |
144 | // the dependency we just disable the warnings. |
145 | #if defined(__clang__) && defined(__has_warning) |
146 | # if __has_warning("-Wsign-compare") |
147 | # pragma clang diagnostic push |
148 | # pragma clang diagnostic ignored "-Wsign-compare" |
149 | # endif |
150 | #elif defined(_MSC_VER) |
151 | # pragma warning(push) |
152 | # pragma warning(disable: 4389) |
153 | #elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 |
154 | # pragma GCC diagnostic push |
155 | # pragma GCC diagnostic ignored "-Wsign-compare" |
156 | #endif |
157 | |
158 | // specialize test output for char pointers to avoid printing as cstring |
159 | template <class T> inline const T& test_output_impl(const T& v) { return v; } |
160 | inline const void* test_output_impl(const char* v) { return v; } |
161 | inline const void* test_output_impl(const unsigned char* v) { return v; } |
162 | inline const void* test_output_impl(const signed char* v) { return v; } |
163 | inline const void* test_output_impl(char* v) { return v; } |
164 | inline const void* test_output_impl(unsigned char* v) { return v; } |
165 | inline const void* test_output_impl(signed char* v) { return v; } |
166 | template<class T> inline const void* test_output_impl(T volatile* v) { return const_cast<T*>(v); } |
167 | |
168 | #if !defined( BOOST_NO_CXX11_NULLPTR ) |
169 | inline const void* test_output_impl(std::nullptr_t) { return nullptr; } |
170 | #endif |
171 | |
172 | // print chars as numeric |
173 | |
174 | inline int test_output_impl( signed char const& v ) { return v; } |
175 | inline unsigned test_output_impl( unsigned char const& v ) { return v; } |
176 | |
177 | // Whether wchar_t is signed is implementation-defined |
178 | |
179 | template<bool Signed> struct lwt_long_type {}; |
180 | template<> struct lwt_long_type<true> { typedef long type; }; |
181 | template<> struct lwt_long_type<false> { typedef unsigned long type; }; |
182 | |
183 | inline lwt_long_type<(static_cast<wchar_t>(-1) < static_cast<wchar_t>(0))>::type test_output_impl( wchar_t const& v ) { return v; } |
184 | |
185 | #if !defined( BOOST_NO_CXX11_CHAR16_T ) |
186 | inline unsigned long test_output_impl( char16_t const& v ) { return v; } |
187 | #endif |
188 | |
189 | #if !defined( BOOST_NO_CXX11_CHAR32_T ) |
190 | inline unsigned long test_output_impl( char32_t const& v ) { return v; } |
191 | #endif |
192 | |
193 | inline std::string test_output_impl( char const& v ) |
194 | { |
195 | if( std::isprint( static_cast<unsigned char>( v ) ) ) |
196 | { |
197 | return std::string( 1, v ); |
198 | } |
199 | else |
200 | { |
201 | static const char char_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; |
202 | char buffer[ 4 ]; |
203 | buffer[ 0 ] = '\\'; |
204 | buffer[ 1 ] = 'x'; |
205 | buffer[ 2 ] = char_table[ (static_cast<unsigned char>( v ) >> 4u) & 0x0f ]; |
206 | buffer[ 3 ] = char_table[ static_cast<unsigned char>( v ) & 0x0f ]; |
207 | |
208 | return std::string( buffer, 4u ); |
209 | } |
210 | } |
211 | |
212 | // predicates |
213 | |
214 | struct lw_test_eq |
215 | { |
216 | template <typename T, typename U> |
217 | bool operator()(const T& t, const U& u) const { return t == u; } |
218 | }; |
219 | |
220 | struct lw_test_ne |
221 | { |
222 | template <typename T, typename U> |
223 | bool operator()(const T& t, const U& u) const { return t != u; } |
224 | }; |
225 | |
226 | struct lw_test_lt |
227 | { |
228 | template <typename T, typename U> |
229 | bool operator()(const T& t, const U& u) const { return t < u; } |
230 | }; |
231 | |
232 | struct lw_test_le |
233 | { |
234 | template <typename T, typename U> |
235 | bool operator()(const T& t, const U& u) const { return t <= u; } |
236 | }; |
237 | |
238 | struct lw_test_gt |
239 | { |
240 | template <typename T, typename U> |
241 | bool operator()(const T& t, const U& u) const { return t > u; } |
242 | }; |
243 | |
244 | struct lw_test_ge |
245 | { |
246 | template <typename T, typename U> |
247 | bool operator()(const T& t, const U& u) const { return t >= u; } |
248 | }; |
249 | |
250 | // lwt_predicate_name |
251 | |
252 | template<class T> char const * lwt_predicate_name( T const& ) |
253 | { |
254 | return "~=" ; |
255 | } |
256 | |
257 | inline char const * lwt_predicate_name( lw_test_eq const& ) |
258 | { |
259 | return "==" ; |
260 | } |
261 | |
262 | inline char const * lwt_predicate_name( lw_test_ne const& ) |
263 | { |
264 | return "!=" ; |
265 | } |
266 | |
267 | inline char const * lwt_predicate_name( lw_test_lt const& ) |
268 | { |
269 | return "<" ; |
270 | } |
271 | |
272 | inline char const * lwt_predicate_name( lw_test_le const& ) |
273 | { |
274 | return "<=" ; |
275 | } |
276 | |
277 | inline char const * lwt_predicate_name( lw_test_gt const& ) |
278 | { |
279 | return ">" ; |
280 | } |
281 | |
282 | inline char const * lwt_predicate_name( lw_test_ge const& ) |
283 | { |
284 | return ">=" ; |
285 | } |
286 | |
287 | // |
288 | |
289 | template<class BinaryPredicate, class T, class U> |
290 | inline bool test_with_impl(BinaryPredicate pred, char const * expr1, char const * expr2, |
291 | char const * file, int line, char const * function, |
292 | T const & t, U const & u) |
293 | { |
294 | if( pred(t, u) ) |
295 | { |
296 | test_results(); |
297 | return true; |
298 | } |
299 | else |
300 | { |
301 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
302 | << file << "(" << line << "): test '" << expr1 << " " << lwt_predicate_name(pred) << " " << expr2 |
303 | << "' ('" << test_output_impl(t) << "' " << lwt_predicate_name(pred) << " '" << test_output_impl(u) |
304 | << "') failed in function '" << function << "'" << std::endl; |
305 | ++test_results().errors(); |
306 | return false; |
307 | } |
308 | } |
309 | |
310 | inline bool test_cstr_eq_impl( char const * expr1, char const * expr2, |
311 | char const * file, int line, char const * function, char const * const t, char const * const u ) |
312 | { |
313 | if( std::strcmp(s1: t, s2: u) == 0 ) |
314 | { |
315 | test_results(); |
316 | return true; |
317 | } |
318 | else |
319 | { |
320 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
321 | << file << "(" << line << "): test '" << expr1 << " == " << expr2 << "' ('" << t |
322 | << "' == '" << u << "') failed in function '" << function << "'" << std::endl; |
323 | ++test_results().errors(); |
324 | return false; |
325 | } |
326 | } |
327 | |
328 | inline bool test_cstr_ne_impl( char const * expr1, char const * expr2, |
329 | char const * file, int line, char const * function, char const * const t, char const * const u ) |
330 | { |
331 | if( std::strcmp(s1: t, s2: u) != 0 ) |
332 | { |
333 | test_results(); |
334 | return true; |
335 | } |
336 | else |
337 | { |
338 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
339 | << file << "(" << line << "): test '" << expr1 << " != " << expr2 << "' ('" << t |
340 | << "' != '" << u << "') failed in function '" << function << "'" << std::endl; |
341 | ++test_results().errors(); |
342 | return false; |
343 | } |
344 | } |
345 | |
346 | template<class FormattedOutputFunction, class InputIterator1, class InputIterator2> |
347 | bool test_all_eq_impl(FormattedOutputFunction& output, |
348 | char const * file, int line, char const * function, |
349 | InputIterator1 first_begin, InputIterator1 first_end, |
350 | InputIterator2 second_begin, InputIterator2 second_end) |
351 | { |
352 | InputIterator1 first_it = first_begin; |
353 | InputIterator2 second_it = second_begin; |
354 | typename std::iterator_traits<InputIterator1>::difference_type first_index = 0; |
355 | typename std::iterator_traits<InputIterator2>::difference_type second_index = 0; |
356 | std::size_t error_count = 0; |
357 | const std::size_t max_count = 8; |
358 | do |
359 | { |
360 | while ((first_it != first_end) && (second_it != second_end) && (*first_it == *second_it)) |
361 | { |
362 | ++first_it; |
363 | ++second_it; |
364 | ++first_index; |
365 | ++second_index; |
366 | } |
367 | if ((first_it == first_end) || (second_it == second_end)) |
368 | { |
369 | break; // do-while |
370 | } |
371 | if (error_count == 0) |
372 | { |
373 | output << file << "(" << line << "): Container contents differ in function '" << function << "':" ; |
374 | } |
375 | else if (error_count >= max_count) |
376 | { |
377 | output << " ..." ; |
378 | break; |
379 | } |
380 | output << " [" << first_index << "] '" << test_output_impl(*first_it) << "' != '" << test_output_impl(*second_it) << "'" ; |
381 | ++first_it; |
382 | ++second_it; |
383 | ++first_index; |
384 | ++second_index; |
385 | ++error_count; |
386 | } while (first_it != first_end); |
387 | |
388 | first_index += std::distance(first_it, first_end); |
389 | second_index += std::distance(second_it, second_end); |
390 | if (first_index != second_index) |
391 | { |
392 | if (error_count == 0) |
393 | { |
394 | output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")" ; |
395 | } |
396 | else |
397 | { |
398 | output << " [*] size(" << first_index << ") != size(" << second_index << ")" ; |
399 | } |
400 | ++error_count; |
401 | } |
402 | |
403 | if (error_count == 0) |
404 | { |
405 | test_results(); |
406 | return true; |
407 | } |
408 | else |
409 | { |
410 | output << std::endl; |
411 | ++test_results().errors(); |
412 | return false; |
413 | } |
414 | } |
415 | |
416 | template<class FormattedOutputFunction, class InputIterator1, class InputIterator2, typename BinaryPredicate> |
417 | bool test_all_with_impl(FormattedOutputFunction& output, |
418 | char const * file, int line, char const * function, |
419 | InputIterator1 first_begin, InputIterator1 first_end, |
420 | InputIterator2 second_begin, InputIterator2 second_end, |
421 | BinaryPredicate predicate) |
422 | { |
423 | InputIterator1 first_it = first_begin; |
424 | InputIterator2 second_it = second_begin; |
425 | typename std::iterator_traits<InputIterator1>::difference_type first_index = 0; |
426 | typename std::iterator_traits<InputIterator2>::difference_type second_index = 0; |
427 | std::size_t error_count = 0; |
428 | const std::size_t max_count = 8; |
429 | do |
430 | { |
431 | while ((first_it != first_end) && (second_it != second_end) && predicate(*first_it, *second_it)) |
432 | { |
433 | ++first_it; |
434 | ++second_it; |
435 | ++first_index; |
436 | ++second_index; |
437 | } |
438 | if ((first_it == first_end) || (second_it == second_end)) |
439 | { |
440 | break; // do-while |
441 | } |
442 | if (error_count == 0) |
443 | { |
444 | output << file << "(" << line << "): Container contents differ in function '" << function << "':" ; |
445 | } |
446 | else if (error_count >= max_count) |
447 | { |
448 | output << " ..." ; |
449 | break; |
450 | } |
451 | output << " [" << first_index << "]" ; |
452 | ++first_it; |
453 | ++second_it; |
454 | ++first_index; |
455 | ++second_index; |
456 | ++error_count; |
457 | } while (first_it != first_end); |
458 | |
459 | first_index += std::distance(first_it, first_end); |
460 | second_index += std::distance(second_it, second_end); |
461 | if (first_index != second_index) |
462 | { |
463 | if (error_count == 0) |
464 | { |
465 | output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")" ; |
466 | } |
467 | else |
468 | { |
469 | output << " [*] size(" << first_index << ") != size(" << second_index << ")" ; |
470 | } |
471 | ++error_count; |
472 | } |
473 | |
474 | if (error_count == 0) |
475 | { |
476 | test_results(); |
477 | return true; |
478 | } |
479 | else |
480 | { |
481 | output << std::endl; |
482 | ++test_results().errors(); |
483 | return false; |
484 | } |
485 | } |
486 | |
487 | #if defined(__clang__) && defined(__has_warning) |
488 | # if __has_warning("-Wsign-compare") |
489 | # pragma clang diagnostic pop |
490 | # endif |
491 | #elif defined(_MSC_VER) |
492 | # pragma warning(pop) |
493 | #elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 |
494 | # pragma GCC diagnostic pop |
495 | #endif |
496 | |
497 | } // namespace detail |
498 | |
499 | inline int report_errors() |
500 | { |
501 | boost::detail::test_result& result = boost::detail::test_results(); |
502 | result.done(); |
503 | |
504 | int errors = result.errors(); |
505 | |
506 | if( errors == 0 ) |
507 | { |
508 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
509 | << "No errors detected." << std::endl; |
510 | } |
511 | else |
512 | { |
513 | BOOST_LIGHTWEIGHT_TEST_OSTREAM |
514 | << errors << " error" << (errors == 1? "" : "s" ) << " detected." << std::endl; |
515 | } |
516 | |
517 | // `return report_errors();` from main only supports 8 bit exit codes |
518 | return errors < 256? errors: 255; |
519 | } |
520 | |
521 | namespace core |
522 | { |
523 | |
524 | inline void lwt_init() |
525 | { |
526 | boost::detail::test_results(); |
527 | } |
528 | |
529 | } // namespace core |
530 | } // namespace boost |
531 | |
532 | #define BOOST_TEST(expr) ( ::boost::detail::test_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, (expr)? true: false) ) |
533 | #define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr)) |
534 | |
535 | #define BOOST_ERROR(msg) ( ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) |
536 | |
537 | #define BOOST_TEST_WITH(expr1,expr2,predicate) ( ::boost::detail::test_with_impl(predicate, #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
538 | |
539 | #define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_eq(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
540 | #define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_ne(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
541 | |
542 | #define BOOST_TEST_LT(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_lt(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
543 | #define BOOST_TEST_LE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_le(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
544 | #define BOOST_TEST_GT(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_gt(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
545 | #define BOOST_TEST_GE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_ge(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
546 | |
547 | #define BOOST_TEST_CSTR_EQ(expr1,expr2) ( ::boost::detail::test_cstr_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
548 | #define BOOST_TEST_CSTR_NE(expr1,expr2) ( ::boost::detail::test_cstr_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) |
549 | |
550 | #define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) ( ::boost::detail::test_all_eq_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2) ) |
551 | #define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) ) |
552 | |
553 | #ifndef BOOST_NO_EXCEPTIONS |
554 | #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ |
555 | try { \ |
556 | EXPR; \ |
557 | ::boost::detail::throw_failed_impl \ |
558 | (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ |
559 | } \ |
560 | catch(EXCEP const&) { \ |
561 | ::boost::detail::test_results(); \ |
562 | } \ |
563 | catch(...) { \ |
564 | ::boost::detail::throw_failed_impl \ |
565 | (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ |
566 | } \ |
567 | // |
568 | #else |
569 | #define BOOST_TEST_THROWS( EXPR, EXCEP ) |
570 | #endif |
571 | |
572 | #ifndef BOOST_NO_EXCEPTIONS |
573 | # define BOOST_TEST_NO_THROW(EXPR) \ |
574 | try { \ |
575 | EXPR; \ |
576 | } catch (const std::exception& e) { \ |
577 | ::boost::detail::no_throw_failed_impl \ |
578 | (#EXPR, e.what(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ |
579 | } catch (...) { \ |
580 | ::boost::detail::no_throw_failed_impl \ |
581 | (#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ |
582 | } |
583 | // |
584 | #else |
585 | # define BOOST_TEST_NO_THROW(EXPR) { EXPR; } |
586 | #endif |
587 | |
588 | #endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP |
589 | |