1 //  (C) Copyright Gennadiy Rozental 2001-2008.
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 //  File        : $RCSfile$
9 //
10 //  Version     : $Revision: 54633 $
11 //
12 //  Description : contains definition for all test tools in test toolbox
13 // ***************************************************************************
14 
15 #ifndef BOOST_TEST_TEST_TOOLS_HPP_012705GER
16 #define BOOST_TEST_TEST_TOOLS_HPP_012705GER
17 
18 // Boost.Test
19 #include <boost/test/predicate_result.hpp>
20 #include <boost/test/unit_test_log.hpp>
21 #include <boost/test/floating_point_comparison.hpp>
22 
23 #include <boost/test/detail/config.hpp>
24 #include <boost/test/detail/global_typedef.hpp>
25 #include <boost/test/detail/workaround.hpp>
26 
27 #include <boost/test/utils/wrap_stringstream.hpp>
28 #include <boost/test/utils/basic_cstring/io.hpp>
29 #include <boost/test/utils/lazy_ostream.hpp>
30 
31 // Boost
32 #include <boost/preprocessor/seq/for_each.hpp>
33 #include <boost/preprocessor/seq/size.hpp>
34 #include <boost/preprocessor/seq/enum.hpp>
35 #include <boost/preprocessor/repetition/repeat.hpp>
36 #include <boost/preprocessor/punctuation/comma_if.hpp>
37 #include <boost/preprocessor/arithmetic/add.hpp>
38 
39 #include <boost/limits.hpp>
40 
41 #include <boost/type_traits/is_array.hpp>
42 #include <boost/type_traits/is_function.hpp>
43 #include <boost/type_traits/is_abstract.hpp>
44 
45 #include <boost/mpl/or.hpp>
46 
47 // STL
48 #include <cstddef>          // for std::size_t
49 #include <iosfwd>
50 #include <ios>              // for std::boolalpha
51 #include <climits>          // for CHAR_BIT
52 
53 #ifdef BOOST_MSVC
54 # pragma warning(disable: 4127) // conditional expression is constant
55 #endif
56 
57 #include <boost/test/detail/suppress_warnings.hpp>
58 
59 //____________________________________________________________________________//
60 
61 // ************************************************************************** //
62 // **************                    TOOL BOX                  ************** //
63 // ************************************************************************** //
64 
65 // In macros below following argument abbreviations are used:
66 // P - predicate
67 // M - message
68 // S - statement
69 // E - exception
70 // L - left argument
71 // R - right argument
72 // TL - tool level
73 // CT - check type
74 // ARGS - arguments list
75 
76 #define BOOST_TEST_TOOL_IMPL( func, P, check_descr, TL, CT )            \
77     ::boost::test_tools::tt_detail::func(                               \
78         P,                                                              \
79         ::boost::unit_test::lazy_ostream::instance() << check_descr,    \
80         BOOST_TEST_L(__FILE__),                                         \
81         static_cast<std::size_t>(__LINE__),                             \
82         ::boost::test_tools::tt_detail::TL,                             \
83         ::boost::test_tools::tt_detail::CT                              \
84 /**/
85 
86 //____________________________________________________________________________//
87 
88 #define BOOST_CHECK_IMPL( P, check_descr, TL, CT )                  \
89 do {                                                                \
90     BOOST_TEST_PASSPOINT();                                         \
91     BOOST_TEST_TOOL_IMPL( check_impl, P, check_descr, TL, CT ), 0 );\
92 } while( ::boost::test_tools::dummy_cond )                          \
93 /**/
94 
95 //____________________________________________________________________________//
96 
97 #define BOOST_TEST_PASS_ARG_INFO( r, data, arg ) , arg, BOOST_STRINGIZE( arg )
98 
99 #define BOOST_CHECK_WITH_ARGS_IMPL( P, check_descr, TL, CT, ARGS )  \
100 do {                                                                \
101     BOOST_TEST_PASSPOINT();                                         \
102     BOOST_TEST_TOOL_IMPL( check_frwd, P, check_descr, TL, CT )      \
103     BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_PASS_ARG_INFO, '_', ARGS ) ); \
104 } while( ::boost::test_tools::dummy_cond )                          \
105 /**/
106 
107 //____________________________________________________________________________//
108 
109 #define BOOST_WARN( P )                     BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED )
110 #define BOOST_CHECK( P )                    BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED )
111 #define BOOST_REQUIRE( P )                  BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED )
112 
113 //____________________________________________________________________________//
114 
115 #define BOOST_WARN_MESSAGE( P, M )          BOOST_CHECK_IMPL( (P), M, WARN, CHECK_MSG )
116 #define BOOST_CHECK_MESSAGE( P, M )         BOOST_CHECK_IMPL( (P), M, CHECK, CHECK_MSG )
117 #define BOOST_REQUIRE_MESSAGE( P, M )       BOOST_CHECK_IMPL( (P), M, REQUIRE, CHECK_MSG )
118 
119 //____________________________________________________________________________//
120 
121 #define BOOST_ERROR( M )                    BOOST_CHECK_MESSAGE( false, M )
122 #define BOOST_FAIL( M )                     BOOST_REQUIRE_MESSAGE( false, M )
123 
124 //____________________________________________________________________________//
125 
126 #define BOOST_CHECK_THROW_IMPL( S, E, P, prefix, TL )                                                   \
127     try {                                                                                               \
128         BOOST_TEST_PASSPOINT();                                                                         \
129         S;                                                                                              \
130         BOOST_CHECK_IMPL( false, "exception " BOOST_STRINGIZE( E ) " is expected", TL, CHECK_MSG ); }   \
131     catch( E const& ex ) {                                                                              \
132         ::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex );                            \
133         BOOST_CHECK_IMPL( P, prefix BOOST_STRINGIZE( E ) " is caught", TL, CHECK_MSG );                 \
134     }                                                                                                   \
135 /**/
136 
137 //____________________________________________________________________________//
138 
139 #define BOOST_WARN_THROW( S, E )            BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", WARN )
140 #define BOOST_CHECK_THROW( S, E )           BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", CHECK )
141 #define BOOST_REQUIRE_THROW( S, E )         BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", REQUIRE )
142 
143 //____________________________________________________________________________//
144 
145 #define BOOST_WARN_EXCEPTION( S, E, P )     BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", WARN )
146 #define BOOST_CHECK_EXCEPTION( S, E, P )    BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", CHECK )
147 #define BOOST_REQUIRE_EXCEPTION( S, E, P )  BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", REQUIRE )
148 
149 //____________________________________________________________________________//
150 
151 #define BOOST_CHECK_NO_THROW_IMPL( S, TL )                                                          \
152     try {                                                                                           \
153         S;                                                                                          \
154         BOOST_CHECK_IMPL( true, "no exceptions thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); } \
155     catch( ... ) {                                                                                  \
156         BOOST_CHECK_IMPL( false, "exception thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG );      \
157     }                                                                                               \
158 /**/
159 
160 #define BOOST_WARN_NO_THROW( S )            BOOST_CHECK_NO_THROW_IMPL( S, WARN )
161 #define BOOST_CHECK_NO_THROW( S )           BOOST_CHECK_NO_THROW_IMPL( S, CHECK )
162 #define BOOST_REQUIRE_NO_THROW( S )         BOOST_CHECK_NO_THROW_IMPL( S, REQUIRE )
163 
164 //____________________________________________________________________________//
165 
166 #define BOOST_WARN_EQUAL( L, R ) \
167     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", WARN, CHECK_EQUAL, (L)(R) )
168 #define BOOST_CHECK_EQUAL( L, R ) \
169     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", CHECK, CHECK_EQUAL, (L)(R) )
170 #define BOOST_REQUIRE_EQUAL( L, R ) \
171     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", REQUIRE, CHECK_EQUAL, (L)(R) )
172 
173 //____________________________________________________________________________//
174 
175 #define BOOST_WARN_NE( L, R ) \
176     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", WARN, CHECK_NE, (L)(R) )
177 #define BOOST_CHECK_NE( L, R ) \
178     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", CHECK, CHECK_NE, (L)(R) )
179 #define BOOST_REQUIRE_NE( L, R ) \
180     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", REQUIRE, CHECK_NE, (L)(R) )
181 
182 //____________________________________________________________________________//
183 
184 #define BOOST_WARN_LT( L, R ) \
185     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", WARN, CHECK_LT, (L)(R) )
186 #define BOOST_CHECK_LT( L, R ) \
187     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", CHECK, CHECK_LT, (L)(R) )
188 #define BOOST_REQUIRE_LT( L, R ) \
189     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", REQUIRE, CHECK_LT, (L)(R) )
190 
191 //____________________________________________________________________________//
192 
193 #define BOOST_WARN_LE( L, R ) \
194     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", WARN, CHECK_LE, (L)(R) )
195 #define BOOST_CHECK_LE( L, R ) \
196     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", CHECK, CHECK_LE, (L)(R) )
197 #define BOOST_REQUIRE_LE( L, R ) \
198     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", REQUIRE, CHECK_LE, (L)(R) )
199 
200 //____________________________________________________________________________//
201 
202 #define BOOST_WARN_GT( L, R ) \
203     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", WARN, CHECK_GT, (L)(R) )
204 #define BOOST_CHECK_GT( L, R ) \
205     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", CHECK, CHECK_GT, (L)(R) )
206 #define BOOST_REQUIRE_GT( L, R ) \
207     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", REQUIRE, CHECK_GT, (L)(R) )
208 
209 //____________________________________________________________________________//
210 
211 #define BOOST_WARN_GE( L, R ) \
212     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", WARN, CHECK_GE, (L)(R) )
213 #define BOOST_CHECK_GE( L, R ) \
214     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", CHECK, CHECK_GE, (L)(R) )
215 #define BOOST_REQUIRE_GE( L, R ) \
216     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", REQUIRE, CHECK_GE, (L)(R) )
217 
218 //____________________________________________________________________________//
219 
220 #define BOOST_WARN_CLOSE( L, R, T ) \
221     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE, \
222         (L)(R)(::boost::test_tools::percent_tolerance(T)) )
223 #define BOOST_CHECK_CLOSE( L, R, T ) \
224     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE, \
225         (L)(R)(::boost::test_tools::percent_tolerance(T)) )
226 #define BOOST_REQUIRE_CLOSE( L, R, T ) \
227     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE, \
228         (L)(R)(::boost::test_tools::percent_tolerance(T)) )
229 
230 //____________________________________________________________________________//
231 
232 #define BOOST_WARN_CLOSE_FRACTION( L, R, T ) \
233     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE_FRACTION, \
234     (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
235 #define BOOST_CHECK_CLOSE_FRACTION( L, R, T ) \
236     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE_FRACTION, \
237     (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
238 #define BOOST_REQUIRE_CLOSE_FRACTION( L, R, T ) \
239     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE_FRACTION, \
240     (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
241 
242 //____________________________________________________________________________//
243 
244 #define BOOST_WARN_SMALL( FPV, T ) \
245     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", WARN, CHECK_SMALL, (FPV)(T) )
246 #define BOOST_CHECK_SMALL( FPV, T ) \
247     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", CHECK, CHECK_SMALL, (FPV)(T) )
248 #define BOOST_REQUIRE_SMALL( FPV, T ) \
249     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", REQUIRE, CHECK_SMALL, (FPV)(T) )
250 
251 //____________________________________________________________________________//
252 
253 #define BOOST_WARN_PREDICATE( P, ARGS ) \
254     BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED_WITH_ARGS, ARGS )
255 #define BOOST_CHECK_PREDICATE( P, ARGS ) \
256     BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED_WITH_ARGS, ARGS )
257 #define BOOST_REQUIRE_PREDICATE( P, ARGS ) \
258     BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED_WITH_ARGS, ARGS )
259 
260 //____________________________________________________________________________//
261 
262 #define BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, TL )      \
263     BOOST_TEST_TOOL_IMPL( check_impl, ::boost::test_tools::tt_detail::equal_coll_impl( \
264         (L_begin), (L_end), (R_begin), (R_end) ), "", TL, CHECK_EQUAL_COLL ),   \
265     4,                                                                          \
266     BOOST_STRINGIZE( L_begin ), BOOST_STRINGIZE( L_end ),                       \
267     BOOST_STRINGIZE( R_begin ), BOOST_STRINGIZE( R_end ) )                      \
268 /**/
269 
270 #define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end )          \
271     BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, WARN )
272 #define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end )         \
273     BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, CHECK )
274 #define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end )       \
275     BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, REQUIRE )
276 
277 //____________________________________________________________________________//
278 
279 #define BOOST_BITWISE_EQUAL_IMPL( L, R, TL )                                    \
280     BOOST_TEST_TOOL_IMPL( check_impl,                                           \
281       ::boost::test_tools::tt_detail::bitwise_equal_impl( (L), (R) ),           \
282       "", TL, CHECK_BITWISE_EQUAL ),                                            \
283     2, BOOST_STRINGIZE( L ), BOOST_STRINGIZE( R ) )                             \
284 /**/
285 
286 #define BOOST_WARN_BITWISE_EQUAL( L, R )    BOOST_BITWISE_EQUAL_IMPL( L, R, WARN )
287 #define BOOST_CHECK_BITWISE_EQUAL( L, R )   BOOST_BITWISE_EQUAL_IMPL( L, R, CHECK )
288 #define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, REQUIRE )
289 
290 //____________________________________________________________________________//
291 
292 #define BOOST_IS_DEFINED( symb )            ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
293 
294 //____________________________________________________________________________//
295 
296 // ***************************** //
297 // deprecated interface
298 
299 #define BOOST_BITWISE_EQUAL( L, R )         BOOST_CHECK_BITWISE_EQUAL( L, R )
300 #define BOOST_MESSAGE( M )                  BOOST_TEST_MESSAGE( M )
301 #define BOOST_CHECKPOINT( M )               BOOST_TEST_CHECKPOINT( M )
302 
303 namespace boost {
304 
305 namespace test_tools {
306 
307 typedef unit_test::const_string      const_string;
308 
309 namespace { bool dummy_cond = false; }
310 
311 // ************************************************************************** //
312 // **************                print_log_value               ************** //
313 // ************************************************************************** //
314 
315 template<typename T>
316 struct print_log_value {
operator ()boost::test_tools::print_log_value317     void    operator()( std::ostream& ostr, T const& t )
318     {
319         // avoid warning: 'boost::test_tools::<unnamed>::dummy_cond' defined but not used
320         if (::boost::test_tools::dummy_cond) {}
321 
322         typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type cant_use_nl;
323 
324         set_precision( ostr, cant_use_nl() );
325 
326         ostr << t; // by default print the value
327     }
328 
set_precisionboost::test_tools::print_log_value329     void set_precision( std::ostream& ostr, mpl::false_ )
330     {
331         if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 )
332             ostr.precision( 2 + std::numeric_limits<T>::digits * 301/1000 );
333     }
334 
set_precisionboost::test_tools::print_log_value335     void set_precision( std::ostream&, mpl::true_ ) {}
336 };
337 
338 //____________________________________________________________________________//
339 
340 #define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type )         \
341 namespace boost { namespace test_tools {                    \
342 template<>                                                  \
343 struct print_log_value<the_type > {                         \
344     void operator()( std::ostream&, the_type const& ) {}    \
345 };                                                          \
346 }}                                                          \
347 /**/
348 
349 //____________________________________________________________________________//
350 
351 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
352 template<typename T, std::size_t N >
353 struct print_log_value< T[N] > {
operator ()boost::test_tools::print_log_value354     void    operator()( std::ostream& ostr, T const* t )
355     {
356         ostr << t;
357     }
358 };
359 #endif
360 
361 //____________________________________________________________________________//
362 
363 template<>
364 struct BOOST_TEST_DECL print_log_value<bool> {
operator ()boost::test_tools::print_log_value365     void    operator()( std::ostream& ostr, bool t )
366     {
367          ostr << std::boolalpha << t;
368     }
369 };
370 
371 //____________________________________________________________________________//
372 
373 template<>
374 struct BOOST_TEST_DECL print_log_value<char> {
375     void    operator()( std::ostream& ostr, char t );
376 };
377 
378 //____________________________________________________________________________//
379 
380 template<>
381 struct BOOST_TEST_DECL print_log_value<unsigned char> {
382     void    operator()( std::ostream& ostr, unsigned char t );
383 };
384 
385 //____________________________________________________________________________//
386 
387 template<>
388 struct BOOST_TEST_DECL print_log_value<char const*> {
389     void    operator()( std::ostream& ostr, char const* t );
390 };
391 
392 //____________________________________________________________________________//
393 
394 template<>
395 struct BOOST_TEST_DECL print_log_value<wchar_t const*> {
396     void    operator()( std::ostream& ostr, wchar_t const* t );
397 };
398 
399 //____________________________________________________________________________//
400 
401 namespace tt_detail {
402 
403 // ************************************************************************** //
404 // **************              tools classification            ************** //
405 // ************************************************************************** //
406 
407 enum check_type {
408     CHECK_PRED,
409     CHECK_MSG,
410     CHECK_EQUAL,
411     CHECK_NE,
412     CHECK_LT,
413     CHECK_LE,
414     CHECK_GT,
415     CHECK_GE,
416     CHECK_CLOSE,
417     CHECK_CLOSE_FRACTION,
418     CHECK_SMALL,
419     CHECK_BITWISE_EQUAL,
420     CHECK_PRED_WITH_ARGS,
421     CHECK_EQUAL_COLL
422 };
423 
424 enum tool_level {
425     WARN, CHECK, REQUIRE, PASS
426 };
427 
428 // ************************************************************************** //
429 // **************                 print_helper                 ************** //
430 // ************************************************************************** //
431 // Adds level of indirection to the output operation, allowing us to customize
432 // it for types that do not support operator << directly or for any other reason
433 
434 template<typename T>
435 struct print_helper_t {
print_helper_tboost::test_tools::tt_detail::print_helper_t436     explicit    print_helper_t( T const& t ) : m_t( t ) {}
437 
438     T const&    m_t;
439 };
440 
441 //____________________________________________________________________________//
442 
443 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
444 // Borland suffers premature pointer decay passing arrays by reference
445 template<typename T, std::size_t N >
446 struct print_helper_t< T[N] > {
print_helper_tboost::test_tools::tt_detail::print_helper_t447     explicit    print_helper_t( T const * t ) : m_t( t ) {}
448 
449     T const *   m_t;
450 };
451 #endif
452 
453 //____________________________________________________________________________//
454 
455 template<typename T>
print_helper(T const & t)456 inline print_helper_t<T> print_helper( T const& t )
457 {
458     return print_helper_t<T>( t );
459 }
460 
461 //____________________________________________________________________________//
462 
463 template<typename T>
464 inline std::ostream&
operator <<(std::ostream & ostr,print_helper_t<T> const & ph)465 operator<<( std::ostream& ostr, print_helper_t<T> const& ph )
466 {
467     print_log_value<T>()( ostr, ph.m_t );
468 
469     return ostr;
470 }
471 
472 //____________________________________________________________________________//
473 
474 // ************************************************************************** //
475 // **************            TOOL BOX Implementation           ************** //
476 // ************************************************************************** //
477 
478 BOOST_TEST_DECL
479 bool check_impl( predicate_result const& pr, ::boost::unit_test::lazy_ostream const& check_descr,
480                  const_string file_name, std::size_t line_num,
481                  tool_level tl, check_type ct,
482                  std::size_t num_args, ... );
483 
484 //____________________________________________________________________________//
485 
486 #define TEMPL_PARAMS( z, m, dummy ) , typename BOOST_JOIN( Arg, m )
487 #define FUNC_PARAMS( z, m, dummy )                                                  \
488  , BOOST_JOIN( Arg, m ) const& BOOST_JOIN( arg, m )                                 \
489  , char const* BOOST_JOIN( BOOST_JOIN( arg, m ), _descr )                           \
490 /**/
491 
492 #define PRED_PARAMS( z, m, dummy ) BOOST_PP_COMMA_IF( m ) BOOST_JOIN( arg, m )
493 
494 #define ARG_INFO( z, m, dummy )                                                     \
495  , BOOST_JOIN( BOOST_JOIN( arg, m ), _descr )                                       \
496  , &static_cast<const unit_test::lazy_ostream&>(unit_test::lazy_ostream::instance() \
497         << ::boost::test_tools::tt_detail::print_helper( BOOST_JOIN( arg, m ) ))    \
498 /**/
499 
500 #define IMPL_FRWD( z, n, dummy )                                                    \
501 template<typename Pred                                                              \
502          BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), TEMPL_PARAMS, _ )>            \
503 inline bool                                                                         \
504 check_frwd( Pred P, unit_test::lazy_ostream const& check_descr,                     \
505             const_string file_name, std::size_t line_num,                           \
506             tool_level tl, check_type ct                                            \
507             BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), FUNC_PARAMS, _ )           \
508 )                                                                                   \
509 {                                                                                   \
510     return                                                                          \
511     check_impl( P( BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), PRED_PARAMS, _ ) ), \
512                 check_descr, file_name, line_num, tl, ct,                           \
513                 BOOST_PP_ADD( n, 1 )                                                \
514                 BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), ARG_INFO, _ )          \
515     );                                                                              \
516 }                                                                                   \
517 /**/
518 
519 #ifndef BOOST_TEST_MAX_PREDICATE_ARITY
520 #define BOOST_TEST_MAX_PREDICATE_ARITY 5
521 #endif
522 
BOOST_PP_REPEAT(BOOST_TEST_MAX_PREDICATE_ARITY,IMPL_FRWD,_)523 BOOST_PP_REPEAT( BOOST_TEST_MAX_PREDICATE_ARITY, IMPL_FRWD, _ )
524 
525 #undef TEMPL_PARAMS
526 #undef FUNC_PARAMS
527 #undef PRED_INFO
528 #undef ARG_INFO
529 #undef IMPL_FRWD
530 
531 //____________________________________________________________________________//
532 
533 template <class Left, class Right>
534 predicate_result equal_impl( Left const& left, Right const& right )
535 {
536     return left == right;
537 }
538 
539 //____________________________________________________________________________//
540 
541 predicate_result        BOOST_TEST_DECL equal_impl( char const* left, char const* right );
equal_impl(char * left,char const * right)542 inline predicate_result equal_impl( char* left, char const* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
equal_impl(char const * left,char * right)543 inline predicate_result equal_impl( char const* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
equal_impl(char * left,char * right)544 inline predicate_result equal_impl( char* left, char* right )       { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
545 
546 #if !defined( BOOST_NO_CWCHAR )
547 predicate_result        BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right );
equal_impl(wchar_t * left,wchar_t const * right)548 inline predicate_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
equal_impl(wchar_t const * left,wchar_t * right)549 inline predicate_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
equal_impl(wchar_t * left,wchar_t * right)550 inline predicate_result equal_impl( wchar_t* left, wchar_t* right )       { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
551 #endif
552 
553 //____________________________________________________________________________//
554 
555 struct equal_impl_frwd {
556     template <typename Left, typename Right>
557     inline predicate_result
call_implboost::test_tools::tt_detail::equal_impl_frwd558     call_impl( Left const& left, Right const& right, mpl::false_ ) const
559     {
560         return equal_impl( left, right );
561     }
562 
563     template <typename Left, typename Right>
564     inline predicate_result
call_implboost::test_tools::tt_detail::equal_impl_frwd565     call_impl( Left const& left, Right const& right, mpl::true_ ) const
566     {
567         return (*this)( right, &left[0] );
568     }
569 
570     template <typename Left, typename Right>
571     inline predicate_result
operator ()boost::test_tools::tt_detail::equal_impl_frwd572     operator()( Left const& left, Right const& right ) const
573     {
574         typedef typename is_array<Left>::type left_is_array;
575         return call_impl( left, right, left_is_array() );
576     }
577 };
578 
579 //____________________________________________________________________________//
580 
581 struct ne_impl {
582     template <class Left, class Right>
operator ()boost::test_tools::tt_detail::ne_impl583     predicate_result operator()( Left const& left, Right const& right )
584     {
585         return !equal_impl_frwd()( left, right );
586     }
587 };
588 
589 //____________________________________________________________________________//
590 
591 struct lt_impl {
592     template <class Left, class Right>
operator ()boost::test_tools::tt_detail::lt_impl593     predicate_result operator()( Left const& left, Right const& right )
594     {
595         return left < right;
596     }
597 };
598 
599 //____________________________________________________________________________//
600 
601 struct le_impl {
602     template <class Left, class Right>
operator ()boost::test_tools::tt_detail::le_impl603     predicate_result operator()( Left const& left, Right const& right )
604     {
605         return left <= right;
606     }
607 };
608 
609 //____________________________________________________________________________//
610 
611 struct gt_impl {
612     template <class Left, class Right>
operator ()boost::test_tools::tt_detail::gt_impl613     predicate_result operator()( Left const& left, Right const& right )
614     {
615         return left > right;
616     }
617 };
618 
619 //____________________________________________________________________________//
620 
621 struct ge_impl {
622     template <class Left, class Right>
operator ()boost::test_tools::tt_detail::ge_impl623     predicate_result operator()( Left const& left, Right const& right )
624     {
625         return left >= right;
626     }
627 };
628 
629 //____________________________________________________________________________//
630 
631 template <typename Left, typename Right>
632 inline predicate_result
equal_coll_impl(Left left_begin,Left left_end,Right right_begin,Right right_end)633 equal_coll_impl( Left left_begin, Left left_end, Right right_begin, Right right_end )
634 {
635     predicate_result    res( true );
636     std::size_t         pos = 0;
637 
638     for( ; left_begin != left_end && right_begin != right_end; ++left_begin, ++right_begin, ++pos ) {
639         if( *left_begin != *right_begin ) {
640             res = false;
641             res.message() << "\nMismatch in a position " << pos << ": "  << *left_begin << " != " << *right_begin;
642         }
643     }
644 
645     if( left_begin != left_end ) {
646         std::size_t r_size = pos;
647         while( left_begin != left_end ) {
648             ++pos;
649             ++left_begin;
650         }
651 
652         res = false;
653         res.message() << "\nCollections size mismatch: " << pos << " != " << r_size;
654     }
655 
656     if( right_begin != right_end ) {
657         std::size_t l_size = pos;
658         while( right_begin != right_end ) {
659             ++pos;
660             ++right_begin;
661         }
662 
663         res = false;
664         res.message() << "\nCollections size mismatch: " << l_size << " != " << pos;
665     }
666 
667     return res;
668 }
669 
670 //____________________________________________________________________________//
671 
672 template <class Left, class Right>
673 inline predicate_result
bitwise_equal_impl(Left const & left,Right const & right)674 bitwise_equal_impl( Left const& left, Right const& right )
675 {
676     predicate_result    res( true );
677 
678     std::size_t left_bit_size  = sizeof(Left)*CHAR_BIT;
679     std::size_t right_bit_size = sizeof(Right)*CHAR_BIT;
680 
681     static Left const leftOne( 1 );
682     static Right const rightOne( 1 );
683 
684     std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size;
685 
686     for( std::size_t counter = 0; counter < total_bits; ++counter ) {
687         if( ( left & ( leftOne << counter ) ) != ( right & ( rightOne << counter ) ) ) {
688             res = false;
689             res.message() << "\nMismatch in a position " << counter;
690         }
691     }
692 
693     if( left_bit_size != right_bit_size ) {
694         res = false;
695         res.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
696     }
697 
698     return res;
699 }
700 
701 //____________________________________________________________________________//
702 
703 bool BOOST_TEST_DECL is_defined_impl( const_string symbol_name, const_string symbol_value );
704 
705 //____________________________________________________________________________//
706 
707 } // namespace tt_detail
708 
709 } // namespace test_tools
710 
711 namespace test_toolbox = test_tools;
712 
713 } // namespace boost
714 
715 //____________________________________________________________________________//
716 
717 #include <boost/test/detail/enable_warnings.hpp>
718 
719 #endif // BOOST_TEST_TEST_TOOLS_HPP_012705GER
720