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