os/ossrv/ossrv_pub/boost_apis/boost/test/test_tools.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 //  (C) Copyright Gennadiy Rozental 2001-2005.
     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: test_tools.hpp,v $
     9 //
    10 //  Version     : $Revision: 1.60.2.7 $
    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 
    22 #include <boost/test/detail/config.hpp>
    23 #include <boost/test/detail/global_typedef.hpp>
    24 #include <boost/test/detail/workaround.hpp>
    25 
    26 #include <boost/test/utils/wrap_stringstream.hpp>
    27 #include <boost/test/utils/basic_cstring/io.hpp>
    28 
    29 // Boost
    30 #include <boost/preprocessor/seq/for_each.hpp>
    31 #include <boost/preprocessor/seq/size.hpp>
    32 #include <boost/preprocessor/seq/enum.hpp> 
    33 #include <boost/preprocessor/repetition/repeat.hpp>
    34 #include <boost/preprocessor/punctuation/comma_if.hpp>
    35 #include <boost/preprocessor/arithmetic/add.hpp>
    36 #include <boost/limits.hpp>
    37 
    38 #include <boost/type_traits/is_array.hpp>
    39 #include <boost/type_traits/is_function.hpp>
    40 #include <boost/type_traits/is_abstract.hpp>
    41 
    42 #include <boost/mpl/or.hpp>
    43 
    44 // STL
    45 #include <cstddef>          // for std::size_t
    46 #include <iosfwd>
    47 
    48 #include <boost/test/detail/suppress_warnings.hpp>
    49 
    50 //____________________________________________________________________________//
    51 
    52 // ************************************************************************** //
    53 // **************                    TOOL BOX                  ************** //
    54 // ************************************************************************** //
    55 
    56 // In macros below following argument abbreviations are used:
    57 // P - predicate
    58 // M - message
    59 // S - statement
    60 // E - exception
    61 // L - left argument
    62 // R - right argument
    63 // TL - tool level
    64 // CT - check type
    65 // ARGS - arguments list
    66 
    67 #define BOOST_TEST_TOOL_IMPL( func, P, check_descr, TL, CT ) \
    68     ::boost::test_tools::tt_detail::func(                    \
    69         P,                                                   \
    70         ::boost::wrap_stringstream().ref() << check_descr,   \
    71         BOOST_TEST_L(__FILE__),                              \
    72         (std::size_t)__LINE__,                               \
    73         ::boost::test_tools::tt_detail::TL,                  \
    74         ::boost::test_tools::tt_detail::CT                   \
    75 /**/
    76 
    77 //____________________________________________________________________________//
    78 
    79 #define BOOST_CHECK_IMPL( P, check_descr, TL, CT )                  \
    80 do {                                                                \
    81     BOOST_TEST_PASSPOINT();                                         \
    82     BOOST_TEST_TOOL_IMPL( check_impl, P, check_descr, TL, CT ), 0 );\
    83 } while( ::boost::test_tools::dummy_cond )                          \
    84 /**/
    85 
    86 //____________________________________________________________________________//
    87 
    88 #define BOOST_TEST_PASS_ARG_INFO( r, data, arg ) , arg, BOOST_STRINGIZE( arg )
    89 
    90 #define BOOST_CHECK_WITH_ARGS_IMPL( P, check_descr, TL, CT, ARGS )  \
    91 do {                                                                \
    92     BOOST_TEST_PASSPOINT();                                         \
    93     BOOST_TEST_TOOL_IMPL( check_frwd, P, check_descr, TL, CT )      \
    94     BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_PASS_ARG_INFO, '_', ARGS ) ); \
    95 } while( ::boost::test_tools::dummy_cond )                          \
    96 /**/
    97 
    98 //____________________________________________________________________________//
    99 
   100 #define BOOST_WARN( P )                     BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED )
   101 #define BOOST_CHECK( P )                    BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED )
   102 #define BOOST_REQUIRE( P )                  BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED )
   103 
   104 //____________________________________________________________________________//
   105 
   106 #define BOOST_WARN_MESSAGE( P, M )          BOOST_CHECK_IMPL( (P), M, WARN, CHECK_MSG )
   107 #define BOOST_CHECK_MESSAGE( P, M )         BOOST_CHECK_IMPL( (P), M, CHECK, CHECK_MSG )
   108 #define BOOST_REQUIRE_MESSAGE( P, M )       BOOST_CHECK_IMPL( (P), M, REQUIRE, CHECK_MSG )
   109 
   110 //____________________________________________________________________________//
   111 
   112 #define BOOST_ERROR( M )                    BOOST_CHECK_MESSAGE( false, M )
   113 #define BOOST_FAIL( M )                     BOOST_REQUIRE_MESSAGE( false, M )
   114 
   115 //____________________________________________________________________________//
   116 
   117 #define BOOST_CHECK_THROW_IMPL( S, E, P, prefix, TL )                                                   \
   118     try {                                                                                               \
   119         BOOST_TEST_PASSPOINT();                                                                         \
   120         S;                                                                                              \
   121         BOOST_CHECK_IMPL( false, "exception " BOOST_STRINGIZE( E ) " is expected", TL, CHECK_MSG ); }   \
   122     catch( E const& ex ) {                                                                              \
   123         ::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex );                            \
   124         BOOST_CHECK_IMPL( P, prefix BOOST_STRINGIZE( E ) " is caught", TL, CHECK_MSG );                 \
   125     }                                                                                                   \
   126 /**/
   127 
   128 //____________________________________________________________________________//
   129 
   130 #define BOOST_WARN_THROW( S, E )            BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", WARN )
   131 #define BOOST_CHECK_THROW( S, E )           BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", CHECK )
   132 #define BOOST_REQUIRE_THROW( S, E )         BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", REQUIRE )
   133 
   134 //____________________________________________________________________________//
   135 
   136 #define BOOST_WARN_EXCEPTION( S, E, P )     BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", WARN )
   137 #define BOOST_CHECK_EXCEPTION( S, E, P )    BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", CHECK )
   138 #define BOOST_REQUIRE_EXCEPTION( S, E, P )  BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", REQUIRE )
   139 
   140 //____________________________________________________________________________//
   141 
   142 #define BOOST_CHECK_NO_THROW_IMPL( S, TL )                                                          \
   143     try {                                                                                           \
   144         S;                                                                                          \
   145         BOOST_CHECK_IMPL( true, "no exceptions thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); } \
   146     catch( ... ) {                                                                                  \
   147         BOOST_CHECK_IMPL( false, "exception thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG );      \
   148     }                                                                                               \
   149 /**/
   150 
   151 #define BOOST_WARN_NO_THROW( S )            BOOST_CHECK_NO_THROW_IMPL( S, WARN )
   152 #define BOOST_CHECK_NO_THROW( S )           BOOST_CHECK_NO_THROW_IMPL( S, CHECK )
   153 #define BOOST_REQUIRE_NO_THROW( S )         BOOST_CHECK_NO_THROW_IMPL( S, REQUIRE )
   154 
   155 //____________________________________________________________________________//
   156 
   157 // The argument version of the following macros are causing "Internal Compiler Errors"
   158 // on MSVC 6.5 when inlining is turned on (i.e. usually in release builds)
   159 #if BOOST_WORKAROUND(BOOST_MSVC, <=1200) && defined(NDEBUG)
   160 #define BOOST_WARN_EQUAL( L, R ) BOOST_WARN( (L) == (R) )
   161 #define BOOST_CHECK_EQUAL( L, R ) BOOST_CHECK( (L) == (R) )
   162 #define BOOST_REQUIRE_EQUAL( L, R ) BOOST_REQUIRE( (L) == (R) )
   163 #else
   164 #define BOOST_WARN_EQUAL( L, R ) \
   165     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", WARN, CHECK_EQUAL, (L)(R) )
   166 #define BOOST_CHECK_EQUAL( L, R ) \
   167     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", CHECK, CHECK_EQUAL, (L)(R) )
   168 #define BOOST_REQUIRE_EQUAL( L, R ) \
   169     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", REQUIRE, CHECK_EQUAL, (L)(R) )
   170 #endif
   171 //____________________________________________________________________________//
   172 
   173 #define BOOST_WARN_CLOSE( L, R, T ) \
   174     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE, \
   175         (L)(R)(::boost::test_tools::percent_tolerance(T)) )
   176 #define BOOST_CHECK_CLOSE( L, R, T ) \
   177     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE, \
   178         (L)(R)(::boost::test_tools::percent_tolerance(T)) )
   179 #define BOOST_REQUIRE_CLOSE( L, R, T ) \
   180     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE, \
   181         (L)(R)(::boost::test_tools::percent_tolerance(T)) )
   182 
   183 //____________________________________________________________________________//
   184 
   185 #define BOOST_WARN_CLOSE_FRACTION( L, R, T ) \
   186     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE_FRACTION, \
   187     (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
   188 #define BOOST_CHECK_CLOSE_FRACTION( L, R, T ) \
   189     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE_FRACTION, \
   190     (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
   191 #define BOOST_REQUIRE_CLOSE_FRACTION( L, R, T ) \
   192     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE_FRACTION, \
   193     (L)(R)(::boost::test_tools::fraction_tolerance(T)) )
   194 
   195 //____________________________________________________________________________//
   196 
   197 #define BOOST_WARN_SMALL( FPV, T ) \
   198     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", WARN, CHECK_SMALL, (FPV)(T) )
   199 #define BOOST_CHECK_SMALL( FPV, T ) \
   200     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", CHECK, CHECK_SMALL, (FPV)(T) )
   201 #define BOOST_REQUIRE_SMALL( FPV, T ) \
   202     BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", REQUIRE, CHECK_SMALL, (FPV)(T) )
   203 
   204 //____________________________________________________________________________//
   205 
   206 #define BOOST_WARN_PREDICATE( P, ARGS ) \
   207     BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED_WITH_ARGS, ARGS )
   208 #define BOOST_CHECK_PREDICATE( P, ARGS ) \
   209     BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED_WITH_ARGS, ARGS )
   210 #define BOOST_REQUIRE_PREDICATE( P, ARGS ) \
   211     BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED_WITH_ARGS, ARGS )
   212 
   213 //____________________________________________________________________________//
   214 
   215 #define BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, TL )      \
   216     BOOST_TEST_TOOL_IMPL( check_impl, ::boost::test_tools::tt_detail::equal_coll_impl( \
   217         (L_begin), (L_end), (R_begin), (R_end) ), "", TL, CHECK_EQUAL_COLL ),   \
   218     4,                                                                          \
   219     BOOST_STRINGIZE( L_begin ), BOOST_STRINGIZE( L_end ),                       \
   220     BOOST_STRINGIZE( R_begin ), BOOST_STRINGIZE( R_end ) )                      \
   221 /**/
   222 
   223 #define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end )          \
   224     BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, WARN )
   225 #define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end )         \
   226     BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, CHECK )
   227 #define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end )       \
   228     BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, REQUIRE )
   229 
   230 //____________________________________________________________________________//
   231 
   232 #define BOOST_BITWISE_EQUAL_IMPL( L, R, TL )                                    \
   233     BOOST_TEST_TOOL_IMPL( check_impl,                                           \
   234       ::boost::test_tools::tt_detail::bitwise_equal_impl( (L), (R) ),           \
   235       "", TL, CHECK_BITWISE_EQUAL ),                                            \
   236     2, BOOST_STRINGIZE( L ), BOOST_STRINGIZE( R ) )                             \
   237 /**/
   238 
   239 #define BOOST_WARN_BITWISE_EQUAL( L, R )    BOOST_BITWISE_EQUAL_IMPL( L, R, WARN )
   240 #define BOOST_CHECK_BITWISE_EQUAL( L, R )   BOOST_BITWISE_EQUAL_IMPL( L, R, CHECK )
   241 #define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, REQUIRE )
   242 
   243 //____________________________________________________________________________//
   244 
   245 #define BOOST_IS_DEFINED( symb )            ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
   246 
   247 //____________________________________________________________________________//
   248 
   249 // ***************************** //
   250 // deprecated interface
   251 
   252 #define BOOST_BITWISE_EQUAL( L, R )         BOOST_CHECK_BITWISE_EQUAL( L, R )
   253 #define BOOST_MESSAGE( M )                  BOOST_TEST_MESSAGE( M )
   254 #define BOOST_CHECKPOINT( M )               BOOST_TEST_CHECKPOINT( M )
   255 
   256 namespace boost {
   257 
   258 namespace test_tools {
   259 
   260 typedef unit_test::const_string      const_string;
   261 
   262 namespace { bool dummy_cond = false; }
   263 
   264 namespace tt_detail {
   265 
   266 // ************************************************************************** //
   267 // **************              tools classification            ************** //
   268 // ************************************************************************** //
   269 
   270 enum check_type {
   271     CHECK_PRED, 
   272     CHECK_MSG,
   273     CHECK_EQUAL,
   274     CHECK_CLOSE,
   275     CHECK_CLOSE_FRACTION,
   276     CHECK_SMALL,
   277     CHECK_BITWISE_EQUAL,
   278     CHECK_PRED_WITH_ARGS,
   279     CHECK_EQUAL_COLL
   280 };
   281 
   282 enum tool_level {
   283     WARN, CHECK, REQUIRE, PASS
   284 };
   285 
   286 // ************************************************************************** //
   287 // **************               log print helper               ************** //
   288 // ************************************************************************** //
   289 
   290 template<typename T>
   291 struct print_log_value {
   292     void    operator()( std::ostream& ostr, T const& t )
   293     {
   294         typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type couldnt_use_nl;
   295 
   296         set_precision( ostr, couldnt_use_nl() );
   297 
   298         ostr << t; // by default print the value
   299     }
   300 
   301     void set_precision( std::ostream& ostr, mpl::false_ )
   302     {
   303         if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 )
   304             ostr.precision( 2 + std::numeric_limits<T>::digits * 301/1000 ); 
   305     }
   306 
   307     void set_precision( std::ostream&, mpl::true_ ) {}
   308 };
   309 
   310 //____________________________________________________________________________//
   311 
   312 #define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type )                 \
   313 namespace boost { namespace test_tools { namespace tt_detail {      \
   314 template<>                                                          \
   315 struct print_log_value<the_type > {                                 \
   316     void operator()( std::ostream& ostr, the_type const& t ) {}     \
   317 };                                                                  \
   318 }}}                                                                 \
   319 /**/
   320 
   321 //____________________________________________________________________________//
   322 
   323 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
   324 template<typename T, std::size_t N >
   325 struct print_log_value< T[N] > {
   326     void    operator()( std::ostream& ostr, T const* t )
   327     {
   328         ostr << t;
   329     }
   330 };
   331 #endif
   332 
   333 //____________________________________________________________________________//
   334 
   335 template<>
   336 struct BOOST_TEST_DECL print_log_value<char> {
   337     void    operator()( std::ostream& ostr, char t );
   338 };
   339 
   340 //____________________________________________________________________________//
   341 
   342 template<>
   343 struct BOOST_TEST_DECL print_log_value<unsigned char> {
   344     void    operator()( std::ostream& ostr, unsigned char t );
   345 };
   346 
   347 //____________________________________________________________________________//
   348 
   349 template<>
   350 struct BOOST_TEST_DECL print_log_value<char const*> {
   351     void    operator()( std::ostream& ostr, char const* t );
   352 };
   353 
   354 //____________________________________________________________________________//
   355 
   356 template<>
   357 struct BOOST_TEST_DECL print_log_value<wchar_t const*> {
   358     void    operator()( std::ostream& ostr, wchar_t const* t );
   359 };
   360 
   361 //____________________________________________________________________________//
   362 
   363 template<typename T>
   364 struct print_helper_t {
   365     explicit    print_helper_t( T const& t ) : m_t( t ) {}
   366 
   367     T const&    m_t;
   368 };
   369 
   370 //____________________________________________________________________________//
   371 
   372 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 
   373 // Borland suffers premature pointer decay passing arrays by reference
   374 template<typename T, std::size_t N >
   375 struct print_helper_t< T[N] > {
   376     explicit    print_helper_t( T const * t ) : m_t( t ) {}
   377 
   378     T const *   m_t;
   379 };
   380 #endif
   381 
   382 //____________________________________________________________________________//
   383 
   384 template<typename T>
   385 inline print_helper_t<T> print_helper( T const& t )
   386 {
   387     return print_helper_t<T>( t );
   388 }
   389 
   390 #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x580) 
   391 template<typename T, std::size_t N>
   392 inline print_helper_t<T*> print_helper( T (&t)[N] )
   393 {
   394     return print_helper_t<T*>( &t[0] );
   395 }
   396 #endif
   397 
   398 //____________________________________________________________________________//
   399 
   400 template<typename T>
   401 inline std::ostream& 
   402 operator<<( std::ostream& ostr, print_helper_t<T> const& ph )
   403 {
   404     print_log_value<T>()( ostr, ph.m_t );
   405 
   406     return ostr;
   407 }
   408 
   409 //____________________________________________________________________________//
   410 
   411 // ************************************************************************** //
   412 // **************            TOOL BOX Implementation           ************** //
   413 // ************************************************************************** //
   414 
   415 BOOST_TEST_DECL 
   416 void check_impl( predicate_result const& pr, wrap_stringstream& check_descr,
   417                  const_string file_name, std::size_t line_num,
   418                  tool_level tl, check_type ct,
   419                  std::size_t num_args, ... );
   420 
   421 //____________________________________________________________________________//
   422 
   423 #define TEMPL_PARAMS( z, m, dummy ) , typename BOOST_JOIN( Arg, m )
   424 #define FUNC_PARAMS( z, m, dummy )                                                  \
   425     , BOOST_JOIN( Arg, m ) const& BOOST_JOIN( arg, m )                              \
   426     , char const* BOOST_JOIN( BOOST_JOIN( arg, m ), _descr )                        \
   427 /**/
   428 
   429 #define PRED_PARAMS( z, m, dummy ) BOOST_PP_COMMA_IF( m ) BOOST_JOIN( arg, m ) 
   430 
   431 #define ARG_INFO( z, m, dummy )                                                     \
   432     , BOOST_JOIN( BOOST_JOIN( arg, m ), _descr )                                    \
   433     , (boost::wrap_stringstream().ref()                                             \
   434         << ::boost::test_tools::tt_detail::                                         \
   435             print_helper( BOOST_JOIN( arg, m ) )).str().c_str()                     \
   436 /**/
   437 
   438 #define IMPL_FRWD( z, n, dummy )                                                    \
   439 template<typename Pred                                                              \
   440          BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), TEMPL_PARAMS, _ )>            \
   441 inline void                                                                         \
   442 check_frwd( Pred P, wrap_stringstream& check_descr,                                 \
   443             const_string file_name, std::size_t line_num,                           \
   444             tool_level tl, check_type ct                                            \
   445             BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), FUNC_PARAMS, _ )           \
   446 )                                                                                   \
   447 {                                                                                   \
   448     check_impl( P( BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), PRED_PARAMS, _ ) ), \
   449                 check_descr, file_name, line_num, tl, ct,                           \
   450                 BOOST_PP_ADD( n, 1 )                                                \
   451                 BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), ARG_INFO, _ )          \
   452     );                                                                              \
   453 }                                                                                   \
   454 /**/
   455 
   456 #ifndef BOOST_TEST_MAX_PREDICATE_ARITY
   457 #define BOOST_TEST_MAX_PREDICATE_ARITY 5
   458 #endif
   459 
   460 BOOST_PP_REPEAT( BOOST_TEST_MAX_PREDICATE_ARITY, IMPL_FRWD, _ )
   461 
   462 #undef TEMPL_PARAMS
   463 #undef FUNC_PARAMS
   464 #undef PRED_INFO
   465 #undef ARG_INFO
   466 #undef IMPL_FRWD
   467 
   468 //____________________________________________________________________________//
   469 
   470 template <class Left, class Right>
   471 predicate_result equal_impl( Left const& left, Right const& right )
   472 {
   473     return left == right;
   474 }
   475 
   476 //____________________________________________________________________________//
   477 
   478 predicate_result        BOOST_TEST_DECL equal_impl( char const* left, char const* right );
   479 inline predicate_result BOOST_TEST_DECL equal_impl( char* left, char const* right ) { return equal_impl( (char const*)left, (char const*)right ); }
   480 inline predicate_result BOOST_TEST_DECL equal_impl( char const* left, char* right ) { return equal_impl( (char const*)left, (char const*)right ); }
   481 inline predicate_result BOOST_TEST_DECL equal_impl( char* left, char* right )       { return equal_impl( (char const*)left, (char const*)right ); }
   482 
   483 #if !defined( BOOST_NO_CWCHAR )
   484 predicate_result        equal_impl( wchar_t const* left, wchar_t const* right );
   485 inline predicate_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( (wchar_t const*)left, (wchar_t const*)right ); }
   486 inline predicate_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( (wchar_t const*)left, (wchar_t const*)right ); }
   487 inline predicate_result equal_impl( wchar_t* left, wchar_t* right )       { return equal_impl( (wchar_t const*)left, (wchar_t const*)right ); }
   488 #endif
   489 
   490 //____________________________________________________________________________//
   491 //
   492 // Declaring this class as exported causes linker errors when building
   493 // the serialisation tests with VC6, disable this for now. (JM 2006/10/30)
   494 struct /*BOOST_TEST_DECL*/ equal_impl_frwd {
   495     template <typename Left, typename Right>
   496     inline predicate_result
   497     call_impl( Left const& left, Right const& right, mpl::false_ ) const
   498     {
   499         return equal_impl( left, right );
   500     }
   501 
   502     template <typename Left, typename Right>
   503     inline predicate_result
   504     call_impl( Left const& left, Right const& right, mpl::true_ ) const
   505     {
   506         return (*this)( right, &left[0] );
   507     }
   508 
   509     template <typename Left, typename Right>
   510     inline predicate_result
   511     operator()( Left const& left, Right const& right ) const
   512     {
   513         typedef typename is_array<Left>::type left_is_array;
   514         return call_impl( left, right, left_is_array() );
   515     }
   516 };
   517 
   518 //____________________________________________________________________________//
   519 
   520 template <typename Left, typename Right>
   521 inline predicate_result
   522 equal_coll_impl( Left left_begin, Left left_end, Right right_begin, Right right_end )
   523 {
   524     predicate_result    res( true );
   525     std::size_t         pos = 0;
   526 
   527     for( ; left_begin != left_end && right_begin != right_end; ++left_begin, ++right_begin, ++pos ) {
   528         if( *left_begin != *right_begin ) {
   529             res = false;
   530             res.message() << "\nMismatch in a position " << pos << ": "  << *left_begin << " != " << *right_begin;
   531         }
   532     }
   533 
   534     if( left_begin != left_end ) {
   535         std::size_t r_size = pos;
   536         while( left_begin != left_end ) {
   537             ++pos;
   538             ++left_begin;
   539         }
   540 
   541         res = false;
   542         res.message() << "\nCollections size mismatch: " << pos << " != " << r_size;
   543     }
   544 
   545     if( right_begin != right_end ) {
   546         std::size_t l_size = pos;
   547         while( right_begin != right_end ) {
   548             ++pos;
   549             ++right_begin;
   550         }
   551 
   552         res = false;
   553         res.message() << "\nCollections size mismatch: " << l_size << " != " << pos;
   554     }
   555 
   556     return res;
   557 }
   558 
   559 //____________________________________________________________________________//
   560 
   561 template <class Left, class Right>
   562 inline predicate_result
   563 bitwise_equal_impl( Left const& left, Right const& right )
   564 {
   565     predicate_result    res( true );
   566 
   567     std::size_t left_bit_size  = sizeof(Left)*CHAR_BIT;
   568     std::size_t right_bit_size = sizeof(Right)*CHAR_BIT;
   569 
   570     static Left const  L1( 1 );
   571     static Right const R1( 1 );
   572 
   573     std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size;
   574 
   575     for( std::size_t counter = 0; counter < total_bits; ++counter ) {
   576         if( ( left & ( L1 << counter ) ) != ( right & ( R1 << counter ) ) ) {
   577             res = false;
   578             res.message() << "\nMismatch in a position " << counter;
   579         }
   580     }
   581 
   582     if( left_bit_size != right_bit_size ) {
   583         res = false;
   584         res.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
   585     }
   586 
   587     return res;
   588 }
   589 
   590 //____________________________________________________________________________//
   591 
   592 bool BOOST_TEST_DECL is_defined_impl( const_string symbol_name, const_string symbol_value );
   593 
   594 //____________________________________________________________________________//
   595 
   596 } // namespace tt_detail
   597 
   598 } // namespace test_tools
   599 
   600 namespace test_toolbox = test_tools;
   601 
   602 } // namespace boost
   603 
   604 //____________________________________________________________________________//
   605 
   606 #include <boost/test/detail/enable_warnings.hpp>
   607 
   608 // ***************************************************************************
   609 //  Revision History :
   610 //
   611 //  $Log: test_tools.hpp,v $
   612 //  Revision 1.60.2.7  2007/02/22 17:57:29  speedsnail
   613 //  Make the msvc-6.5 hack even more specific, i.e. apply only in release builds.
   614 //
   615 //  Revision 1.60.2.6  2006/12/16 15:02:16  speedsnail
   616 //  Merged from HEAD
   617 //
   618 //  Revision 1.60.2.5  2006/11/14 21:33:26  jhunold
   619 //  Merge from HEAD: Add missing export macros for print_log_value<>
   620 //
   621 //  Revision 1.60.2.4  2006/11/14 07:35:43  jhunold
   622 //  Merge from HEAD: Removed wrong export declarations.
   623 //
   624 //  Revision 1.60.2.3  2006/11/13 20:06:57  jhunold
   625 //  Merge from HEAD:
   626 //  Added missing export declarations.
   627 //
   628 //  Revision 1.60.2.2  2006/10/30 18:37:36  johnmaddock
   629 //  Patch for serialisation test failures.
   630 //
   631 //  Revision 1.60.2.1  2006/07/24 00:43:17  gennaro_prota
   632 //  Tentative fix for Sun C++ 5.8 (don't add more specialized print_helper function template)
   633 //
   634 //  Revision 1.60  2006/03/19 07:27:11  rogeeff
   635 //  avoid warning
   636 //
   637 //  Revision 1.59  2006/03/03 17:39:46  rogeeff
   638 //  paaspoint added to check throw
   639 //
   640 //  Revision 1.58  2006/02/06 10:04:55  rogeeff
   641 //  BOOST_TEST_MODULE - master test suite name
   642 //
   643 //  Revision 1.57  2006/01/28 07:00:47  rogeeff
   644 //  sunpro port
   645 //
   646 //  Revision 1.56  2005/12/19 03:08:30  rogeeff
   647 //  added is_abstract to guard numeric_limits instantiation
   648 //
   649 //  Revision 1.55  2005/12/14 05:20:41  rogeeff
   650 //  dll support introduced
   651 //  BOOST_TEST_PASSPOINT() introduced
   652 //  BOOST_MESSAGE depricated. Use BOOST_TEST_MESSAGE instead
   653 //  BOOST_CHECKPOINT is depricated. Use BOOST_TEST_CHECKPOINT intead
   654 //
   655 //  Revision 1.54  2005/06/07 04:38:20  rogeeff
   656 //  borland fix
   657 //
   658 //  Revision 1.53  2005/05/11 04:51:14  rogeeff
   659 //  borlard portability fix
   660 //
   661 //  Revision 1.52  2005/03/22 07:08:47  rogeeff
   662 //  string comparisons streamlined
   663 //  precision settings made portable
   664 //
   665 //  Revision 1.51  2005/02/21 10:23:54  rogeeff
   666 //  major issue with TT redesign causing TT to reevaluate it's arguments fixed
   667 //  FP precision extended
   668 //
   669 //  Revision 1.50  2005/02/20 08:27:06  rogeeff
   670 //  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
   671 //
   672 //  Revision 1.49  2005/02/01 06:40:06  rogeeff
   673 //  copyright update
   674 //  old log entries removed
   675 //  minor stylistic changes
   676 //  deprecated tools removed
   677 //
   678 //  Revision 1.48  2005/01/30 03:32:57  rogeeff
   679 //  Test Tools completely reworked:
   680 //    interfaces streamlined to provide 3 version for each tool
   681 //    implementation reworked to use single vararg formatter function
   682 //    CHECK_COLLECTION now expect 4 arguments
   683 //    BITWISE_EQUAL renamed to CHECK_BITWISE_EQUAL but still provided as deprecated
   684 //    CHECK_COLLECTION interface changed to use PP_SEQ and as a result support arbitrary number of predicate arguments
   685 //    most of templates eliminated
   686 //    deprecated tools removed
   687 //    print_helper object generator added
   688 //
   689 // ***************************************************************************
   690 
   691 #endif // BOOST_TEST_TEST_TOOLS_HPP_012705GER
   692