test_tools.hpp 30 KB

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