Chris@16: // (C) Copyright Gennadiy Rozental 2001-2008. Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/libs/test for the library home page. Chris@16: // Chris@16: // File : $RCSfile$ Chris@16: // Chris@101: // Version : $Revision$ Chris@16: // Chris@16: // Description : contains definition for all test tools in test toolbox Chris@16: // *************************************************************************** Chris@16: Chris@16: #ifndef BOOST_TEST_TEST_TOOLS_HPP_012705GER Chris@16: #define BOOST_TEST_TEST_TOOLS_HPP_012705GER Chris@16: Chris@16: // Boost.Test Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Boost Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: // STL Chris@16: #include // for std::size_t Chris@16: #include Chris@16: #include // for std::boolalpha Chris@16: #include // for CHAR_BIT Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: # pragma warning(disable: 4127) // conditional expression is constant Chris@16: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** TOOL BOX ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: // In macros below following argument abbreviations are used: Chris@16: // P - predicate Chris@16: // M - message Chris@16: // S - statement Chris@16: // E - exception Chris@16: // L - left argument Chris@16: // R - right argument Chris@16: // TL - tool level Chris@16: // CT - check type Chris@16: // ARGS - arguments list Chris@16: Chris@16: #define BOOST_TEST_TOOL_IMPL( func, P, check_descr, TL, CT ) \ Chris@16: ::boost::test_tools::tt_detail::func( \ Chris@16: P, \ Chris@16: ::boost::unit_test::lazy_ostream::instance() << check_descr, \ Chris@16: BOOST_TEST_L(__FILE__), \ Chris@16: static_cast(__LINE__), \ Chris@16: ::boost::test_tools::tt_detail::TL, \ Chris@16: ::boost::test_tools::tt_detail::CT \ Chris@16: /**/ Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_CHECK_IMPL( P, check_descr, TL, CT ) \ Chris@16: do { \ Chris@16: BOOST_TEST_PASSPOINT(); \ Chris@16: BOOST_TEST_TOOL_IMPL( check_impl, P, check_descr, TL, CT ), 0 );\ Chris@16: } while( ::boost::test_tools::dummy_cond ) \ Chris@16: /**/ Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_TEST_PASS_ARG_INFO( r, data, arg ) , arg, BOOST_STRINGIZE( arg ) Chris@16: Chris@16: #define BOOST_CHECK_WITH_ARGS_IMPL( P, check_descr, TL, CT, ARGS ) \ Chris@16: do { \ Chris@16: BOOST_TEST_PASSPOINT(); \ Chris@16: BOOST_TEST_TOOL_IMPL( check_frwd, P, check_descr, TL, CT ) \ Chris@16: BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_PASS_ARG_INFO, '_', ARGS ) ); \ Chris@16: } while( ::boost::test_tools::dummy_cond ) \ Chris@16: /**/ Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED ) Chris@16: #define BOOST_CHECK( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED ) Chris@16: #define BOOST_REQUIRE( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, WARN, CHECK_MSG ) Chris@16: #define BOOST_CHECK_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, CHECK, CHECK_MSG ) Chris@16: #define BOOST_REQUIRE_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, REQUIRE, CHECK_MSG ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_ERROR( M ) BOOST_CHECK_MESSAGE( false, M ) Chris@16: #define BOOST_FAIL( M ) BOOST_REQUIRE_MESSAGE( false, M ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_CHECK_THROW_IMPL( S, E, P, prefix, TL ) \ Chris@16: try { \ Chris@16: BOOST_TEST_PASSPOINT(); \ Chris@16: S; \ Chris@16: BOOST_CHECK_IMPL( false, "exception " BOOST_STRINGIZE( E ) " is expected", TL, CHECK_MSG ); } \ Chris@16: catch( E const& ex ) { \ Chris@16: ::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex ); \ Chris@16: BOOST_CHECK_IMPL( P, prefix BOOST_STRINGIZE( E ) " is caught", TL, CHECK_MSG ); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", WARN ) Chris@16: #define BOOST_CHECK_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", CHECK ) Chris@16: #define BOOST_REQUIRE_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", REQUIRE ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", WARN ) Chris@16: #define BOOST_CHECK_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", CHECK ) Chris@16: #define BOOST_REQUIRE_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", REQUIRE ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_CHECK_NO_THROW_IMPL( S, TL ) \ Chris@16: try { \ Chris@16: S; \ Chris@16: BOOST_CHECK_IMPL( true, "no exceptions thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); } \ Chris@16: catch( ... ) { \ Chris@16: BOOST_CHECK_IMPL( false, "exception thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_WARN_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, WARN ) Chris@16: #define BOOST_CHECK_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, CHECK ) Chris@16: #define BOOST_REQUIRE_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, REQUIRE ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_EQUAL( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", WARN, CHECK_EQUAL, (L)(R) ) Chris@16: #define BOOST_CHECK_EQUAL( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", CHECK, CHECK_EQUAL, (L)(R) ) Chris@16: #define BOOST_REQUIRE_EQUAL( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", REQUIRE, CHECK_EQUAL, (L)(R) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_NE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", WARN, CHECK_NE, (L)(R) ) Chris@16: #define BOOST_CHECK_NE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", CHECK, CHECK_NE, (L)(R) ) Chris@16: #define BOOST_REQUIRE_NE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", REQUIRE, CHECK_NE, (L)(R) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_LT( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", WARN, CHECK_LT, (L)(R) ) Chris@16: #define BOOST_CHECK_LT( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", CHECK, CHECK_LT, (L)(R) ) Chris@16: #define BOOST_REQUIRE_LT( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", REQUIRE, CHECK_LT, (L)(R) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_LE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", WARN, CHECK_LE, (L)(R) ) Chris@16: #define BOOST_CHECK_LE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", CHECK, CHECK_LE, (L)(R) ) Chris@16: #define BOOST_REQUIRE_LE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", REQUIRE, CHECK_LE, (L)(R) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_GT( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", WARN, CHECK_GT, (L)(R) ) Chris@16: #define BOOST_CHECK_GT( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", CHECK, CHECK_GT, (L)(R) ) Chris@16: #define BOOST_REQUIRE_GT( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", REQUIRE, CHECK_GT, (L)(R) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_GE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", WARN, CHECK_GE, (L)(R) ) Chris@16: #define BOOST_CHECK_GE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", CHECK, CHECK_GE, (L)(R) ) Chris@16: #define BOOST_REQUIRE_GE( L, R ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", REQUIRE, CHECK_GE, (L)(R) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_CLOSE( L, R, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE, \ Chris@16: (L)(R)(::boost::test_tools::percent_tolerance(T)) ) Chris@16: #define BOOST_CHECK_CLOSE( L, R, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE, \ Chris@16: (L)(R)(::boost::test_tools::percent_tolerance(T)) ) Chris@16: #define BOOST_REQUIRE_CLOSE( L, R, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE, \ Chris@16: (L)(R)(::boost::test_tools::percent_tolerance(T)) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_CLOSE_FRACTION( L, R, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE_FRACTION, \ Chris@16: (L)(R)(::boost::test_tools::fraction_tolerance(T)) ) Chris@16: #define BOOST_CHECK_CLOSE_FRACTION( L, R, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE_FRACTION, \ Chris@16: (L)(R)(::boost::test_tools::fraction_tolerance(T)) ) Chris@16: #define BOOST_REQUIRE_CLOSE_FRACTION( L, R, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE_FRACTION, \ Chris@16: (L)(R)(::boost::test_tools::fraction_tolerance(T)) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_SMALL( FPV, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", WARN, CHECK_SMALL, (FPV)(T) ) Chris@16: #define BOOST_CHECK_SMALL( FPV, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", CHECK, CHECK_SMALL, (FPV)(T) ) Chris@16: #define BOOST_REQUIRE_SMALL( FPV, T ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", REQUIRE, CHECK_SMALL, (FPV)(T) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_WARN_PREDICATE( P, ARGS ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED_WITH_ARGS, ARGS ) Chris@16: #define BOOST_CHECK_PREDICATE( P, ARGS ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED_WITH_ARGS, ARGS ) Chris@16: #define BOOST_REQUIRE_PREDICATE( P, ARGS ) \ Chris@16: BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED_WITH_ARGS, ARGS ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, TL ) \ Chris@16: BOOST_TEST_TOOL_IMPL( check_impl, ::boost::test_tools::tt_detail::equal_coll_impl( \ Chris@16: (L_begin), (L_end), (R_begin), (R_end) ), "", TL, CHECK_EQUAL_COLL ), \ Chris@16: 4, \ Chris@16: BOOST_STRINGIZE( L_begin ), BOOST_STRINGIZE( L_end ), \ Chris@16: BOOST_STRINGIZE( R_begin ), BOOST_STRINGIZE( R_end ) ) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \ Chris@16: BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, WARN ) Chris@16: #define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \ Chris@16: BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, CHECK ) Chris@16: #define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \ Chris@16: BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, REQUIRE ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_BITWISE_EQUAL_IMPL( L, R, TL ) \ Chris@16: BOOST_TEST_TOOL_IMPL( check_impl, \ Chris@16: ::boost::test_tools::tt_detail::bitwise_equal_impl( (L), (R) ), \ Chris@16: "", TL, CHECK_BITWISE_EQUAL ), \ Chris@16: 2, BOOST_STRINGIZE( L ), BOOST_STRINGIZE( R ) ) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_WARN_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, WARN ) Chris@16: #define BOOST_CHECK_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, CHECK ) Chris@16: #define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, REQUIRE ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) ) Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ***************************** // Chris@16: // deprecated interface Chris@16: Chris@16: #define BOOST_BITWISE_EQUAL( L, R ) BOOST_CHECK_BITWISE_EQUAL( L, R ) Chris@16: #define BOOST_MESSAGE( M ) BOOST_TEST_MESSAGE( M ) Chris@16: #define BOOST_CHECKPOINT( M ) BOOST_TEST_CHECKPOINT( M ) Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace test_tools { Chris@16: Chris@16: typedef unit_test::const_string const_string; Chris@16: Chris@16: namespace { bool dummy_cond = false; } Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** print_log_value ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: template Chris@16: struct print_log_value { Chris@16: void operator()( std::ostream& ostr, T const& t ) Chris@16: { Chris@16: // avoid warning: 'boost::test_tools::::dummy_cond' defined but not used Chris@16: if (::boost::test_tools::dummy_cond) {} Chris@16: Chris@16: typedef typename mpl::or_,is_function,is_abstract >::type cant_use_nl; Chris@16: Chris@16: set_precision( ostr, cant_use_nl() ); Chris@16: Chris@16: ostr << t; // by default print the value Chris@16: } Chris@16: Chris@16: void set_precision( std::ostream& ostr, mpl::false_ ) Chris@16: { Chris@16: if( std::numeric_limits::is_specialized && std::numeric_limits::radix == 2 ) Chris@16: ostr.precision( 2 + std::numeric_limits::digits * 301/1000 ); Chris@16: } Chris@16: Chris@16: void set_precision( std::ostream&, mpl::true_ ) {} Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type ) \ Chris@16: namespace boost { namespace test_tools { \ Chris@16: template<> \ Chris@16: struct print_log_value { \ Chris@16: void operator()( std::ostream&, the_type const& ) {} \ Chris@16: }; \ Chris@16: }} \ Chris@16: /**/ Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) Chris@16: template Chris@16: struct print_log_value< T[N] > { Chris@16: void operator()( std::ostream& ostr, T const* t ) Chris@16: { Chris@16: ostr << t; Chris@16: } Chris@16: }; Chris@16: #endif Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template<> Chris@16: struct BOOST_TEST_DECL print_log_value { Chris@16: void operator()( std::ostream& ostr, bool t ) Chris@16: { Chris@16: ostr << std::boolalpha << t; Chris@16: } Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template<> Chris@16: struct BOOST_TEST_DECL print_log_value { Chris@16: void operator()( std::ostream& ostr, char t ); Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template<> Chris@16: struct BOOST_TEST_DECL print_log_value { Chris@16: void operator()( std::ostream& ostr, unsigned char t ); Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template<> Chris@16: struct BOOST_TEST_DECL print_log_value { Chris@16: void operator()( std::ostream& ostr, char const* t ); Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template<> Chris@16: struct BOOST_TEST_DECL print_log_value { Chris@16: void operator()( std::ostream& ostr, wchar_t const* t ); Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: namespace tt_detail { Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** tools classification ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: enum check_type { Chris@16: CHECK_PRED, Chris@16: CHECK_MSG, Chris@16: CHECK_EQUAL, Chris@16: CHECK_NE, Chris@16: CHECK_LT, Chris@16: CHECK_LE, Chris@16: CHECK_GT, Chris@16: CHECK_GE, Chris@16: CHECK_CLOSE, Chris@16: CHECK_CLOSE_FRACTION, Chris@16: CHECK_SMALL, Chris@16: CHECK_BITWISE_EQUAL, Chris@16: CHECK_PRED_WITH_ARGS, Chris@16: CHECK_EQUAL_COLL Chris@16: }; Chris@16: Chris@16: enum tool_level { Chris@16: WARN, CHECK, REQUIRE, PASS Chris@16: }; Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** print_helper ************** // Chris@16: // ************************************************************************** // Chris@16: // Adds level of indirection to the output operation, allowing us to customize Chris@16: // it for types that do not support operator << directly or for any other reason Chris@16: Chris@16: template Chris@16: struct print_helper_t { Chris@16: explicit print_helper_t( T const& t ) : m_t( t ) {} Chris@16: Chris@16: T const& m_t; Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) Chris@16: // Borland suffers premature pointer decay passing arrays by reference Chris@16: template Chris@16: struct print_helper_t< T[N] > { Chris@16: explicit print_helper_t( T const * t ) : m_t( t ) {} Chris@16: Chris@16: T const * m_t; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template Chris@16: inline print_helper_t print_helper( T const& t ) Chris@16: { Chris@16: return print_helper_t( t ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template Chris@16: inline std::ostream& Chris@16: operator<<( std::ostream& ostr, print_helper_t const& ph ) Chris@16: { Chris@16: print_log_value()( ostr, ph.m_t ); Chris@16: Chris@16: return ostr; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** TOOL BOX Implementation ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: BOOST_TEST_DECL Chris@16: bool check_impl( predicate_result const& pr, ::boost::unit_test::lazy_ostream const& check_descr, Chris@16: const_string file_name, std::size_t line_num, Chris@16: tool_level tl, check_type ct, Chris@16: std::size_t num_args, ... ); Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #define TEMPL_PARAMS( z, m, dummy ) , typename BOOST_JOIN( Arg, m ) Chris@16: #define FUNC_PARAMS( z, m, dummy ) \ Chris@16: , BOOST_JOIN( Arg, m ) const& BOOST_JOIN( arg, m ) \ Chris@16: , char const* BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \ Chris@16: /**/ Chris@16: Chris@16: #define PRED_PARAMS( z, m, dummy ) BOOST_PP_COMMA_IF( m ) BOOST_JOIN( arg, m ) Chris@16: Chris@16: #define ARG_INFO( z, m, dummy ) \ Chris@16: , BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \ Chris@16: , &static_cast(unit_test::lazy_ostream::instance() \ Chris@16: << ::boost::test_tools::tt_detail::print_helper( BOOST_JOIN( arg, m ) )) \ Chris@16: /**/ Chris@16: Chris@16: #define IMPL_FRWD( z, n, dummy ) \ Chris@16: template \ Chris@16: inline bool \ Chris@16: check_frwd( Pred P, unit_test::lazy_ostream const& check_descr, \ Chris@16: const_string file_name, std::size_t line_num, \ Chris@16: tool_level tl, check_type ct \ Chris@16: BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), FUNC_PARAMS, _ ) \ Chris@16: ) \ Chris@16: { \ Chris@16: return \ Chris@16: check_impl( P( BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), PRED_PARAMS, _ ) ), \ Chris@16: check_descr, file_name, line_num, tl, ct, \ Chris@16: BOOST_PP_ADD( n, 1 ) \ Chris@16: BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), ARG_INFO, _ ) \ Chris@16: ); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: #ifndef BOOST_TEST_MAX_PREDICATE_ARITY Chris@16: #define BOOST_TEST_MAX_PREDICATE_ARITY 5 Chris@16: #endif Chris@16: Chris@16: BOOST_PP_REPEAT( BOOST_TEST_MAX_PREDICATE_ARITY, IMPL_FRWD, _ ) Chris@16: Chris@16: #undef TEMPL_PARAMS Chris@16: #undef FUNC_PARAMS Chris@16: #undef PRED_INFO Chris@16: #undef ARG_INFO Chris@16: #undef IMPL_FRWD Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template Chris@16: predicate_result equal_impl( Left const& left, Right const& right ) Chris@16: { Chris@16: return left == right; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: predicate_result BOOST_TEST_DECL equal_impl( char const* left, char const* right ); Chris@16: inline predicate_result equal_impl( char* left, char const* right ) { return equal_impl( static_cast(left), static_cast(right) ); } Chris@16: inline predicate_result equal_impl( char const* left, char* right ) { return equal_impl( static_cast(left), static_cast(right) ); } Chris@16: inline predicate_result equal_impl( char* left, char* right ) { return equal_impl( static_cast(left), static_cast(right) ); } Chris@16: Chris@16: #if !defined( BOOST_NO_CWCHAR ) Chris@16: predicate_result BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right ); Chris@16: inline predicate_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( static_cast(left), static_cast(right) ); } Chris@16: inline predicate_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( static_cast(left), static_cast(right) ); } Chris@16: inline predicate_result equal_impl( wchar_t* left, wchar_t* right ) { return equal_impl( static_cast(left), static_cast(right) ); } Chris@16: #endif Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: struct equal_impl_frwd { Chris@16: template Chris@16: inline predicate_result Chris@16: call_impl( Left const& left, Right const& right, mpl::false_ ) const Chris@16: { Chris@16: return equal_impl( left, right ); Chris@16: } Chris@16: Chris@16: template Chris@16: inline predicate_result Chris@16: call_impl( Left const& left, Right const& right, mpl::true_ ) const Chris@16: { Chris@16: return (*this)( right, &left[0] ); Chris@16: } Chris@16: Chris@16: template Chris@16: inline predicate_result Chris@16: operator()( Left const& left, Right const& right ) const Chris@16: { Chris@16: typedef typename is_array::type left_is_array; Chris@16: return call_impl( left, right, left_is_array() ); Chris@16: } Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: struct ne_impl { Chris@16: template Chris@16: predicate_result operator()( Left const& left, Right const& right ) Chris@16: { Chris@16: return !equal_impl_frwd()( left, right ); Chris@16: } Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: struct lt_impl { Chris@16: template Chris@16: predicate_result operator()( Left const& left, Right const& right ) Chris@16: { Chris@16: return left < right; Chris@16: } Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: struct le_impl { Chris@16: template Chris@16: predicate_result operator()( Left const& left, Right const& right ) Chris@16: { Chris@16: return left <= right; Chris@16: } Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: struct gt_impl { Chris@16: template Chris@16: predicate_result operator()( Left const& left, Right const& right ) Chris@16: { Chris@16: return left > right; Chris@16: } Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: struct ge_impl { Chris@16: template Chris@16: predicate_result operator()( Left const& left, Right const& right ) Chris@16: { Chris@16: return left >= right; Chris@16: } Chris@16: }; Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template Chris@16: inline predicate_result Chris@16: equal_coll_impl( Left left_begin, Left left_end, Right right_begin, Right right_end ) Chris@16: { Chris@16: predicate_result res( true ); Chris@16: std::size_t pos = 0; Chris@16: Chris@16: for( ; left_begin != left_end && right_begin != right_end; ++left_begin, ++right_begin, ++pos ) { Chris@16: if( *left_begin != *right_begin ) { Chris@16: res = false; Chris@16: res.message() << "\nMismatch in a position " << pos << ": " << *left_begin << " != " << *right_begin; Chris@16: } Chris@16: } Chris@16: Chris@16: if( left_begin != left_end ) { Chris@16: std::size_t r_size = pos; Chris@16: while( left_begin != left_end ) { Chris@16: ++pos; Chris@16: ++left_begin; Chris@16: } Chris@16: Chris@16: res = false; Chris@16: res.message() << "\nCollections size mismatch: " << pos << " != " << r_size; Chris@16: } Chris@16: Chris@16: if( right_begin != right_end ) { Chris@16: std::size_t l_size = pos; Chris@16: while( right_begin != right_end ) { Chris@16: ++pos; Chris@16: ++right_begin; Chris@16: } Chris@16: Chris@16: res = false; Chris@16: res.message() << "\nCollections size mismatch: " << l_size << " != " << pos; Chris@16: } Chris@16: Chris@16: return res; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: template Chris@16: inline predicate_result Chris@16: bitwise_equal_impl( Left const& left, Right const& right ) Chris@16: { Chris@16: predicate_result res( true ); Chris@16: Chris@16: std::size_t left_bit_size = sizeof(Left)*CHAR_BIT; Chris@16: std::size_t right_bit_size = sizeof(Right)*CHAR_BIT; Chris@16: Chris@16: static Left const leftOne( 1 ); Chris@16: static Right const rightOne( 1 ); Chris@16: Chris@16: std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size; Chris@16: Chris@16: for( std::size_t counter = 0; counter < total_bits; ++counter ) { Chris@16: if( ( left & ( leftOne << counter ) ) != ( right & ( rightOne << counter ) ) ) { Chris@16: res = false; Chris@16: res.message() << "\nMismatch in a position " << counter; Chris@16: } Chris@16: } Chris@16: Chris@16: if( left_bit_size != right_bit_size ) { Chris@16: res = false; Chris@16: res.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size; Chris@16: } Chris@16: Chris@16: return res; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: bool BOOST_TEST_DECL is_defined_impl( const_string symbol_name, const_string symbol_value ); Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: } // namespace tt_detail Chris@16: Chris@16: } // namespace test_tools Chris@16: Chris@16: namespace test_toolbox = test_tools; Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_TEST_TEST_TOOLS_HPP_012705GER