| 1 | // (C) Copyright Gennadiy Rozental 2001. |
| 2 | // Distributed under the Boost Software License, Version 1.0. |
| 3 | // (See accompanying file LICENSE_1_0.txt or copy at |
| 4 | // http://www.boost.org/LICENSE_1_0.txt) |
| 5 | |
| 6 | // See http://www.boost.org/libs/test for the library home page. |
| 7 | // |
| 8 | // File : $RCSfile$ |
| 9 | // |
| 10 | // Version : $Revision: 74248 $ |
| 11 | // |
| 12 | // Description : implementation details for old toolbox |
| 13 | // *************************************************************************** |
| 14 | |
| 15 | #ifndef BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER |
| 16 | #define BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER |
| 17 | |
| 18 | // Boost.Test |
| 19 | #include <boost/test/unit_test_log.hpp> |
| 20 | #include <boost/test/tools/assertion_result.hpp> |
| 21 | #include <boost/test/tools/floating_point_comparison.hpp> |
| 22 | |
| 23 | #include <boost/test/tools/detail/fwd.hpp> |
| 24 | #include <boost/test/tools/detail/print_helper.hpp> |
| 25 | |
| 26 | // Boost |
| 27 | #include <boost/limits.hpp> |
| 28 | #include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits |
| 29 | #include <boost/type_traits/is_array.hpp> |
| 30 | |
| 31 | #include <boost/preprocessor/repetition/repeat.hpp> |
| 32 | #include <boost/preprocessor/arithmetic/add.hpp> |
| 33 | |
| 34 | // STL |
| 35 | #include <cstddef> // for std::size_t |
| 36 | #include <climits> // for CHAR_BIT |
| 37 | |
| 38 | #include <boost/test/detail/suppress_warnings.hpp> |
| 39 | |
| 40 | //____________________________________________________________________________// |
| 41 | |
| 42 | namespace boost { |
| 43 | namespace test_tools { |
| 44 | namespace tt_detail { |
| 45 | |
| 46 | // ************************************************************************** // |
| 47 | // ************** old TOOLBOX Implementation ************** // |
| 48 | // ************************************************************************** // |
| 49 | |
| 50 | // This function adds level of indirection, but it makes sure we evaluate predicate |
| 51 | // arguments only once |
| 52 | |
| 53 | #ifndef BOOST_TEST_PROD |
| 54 | #define TEMPL_PARAMS( z, m, dummy ) , typename BOOST_JOIN( Arg, m ) |
| 55 | |
| 56 | #define FUNC_PARAMS( z, m, dummy ) \ |
| 57 | , BOOST_JOIN( Arg, m ) const& BOOST_JOIN( arg, m ) \ |
| 58 | , char const* BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \ |
| 59 | /**/ |
| 60 | |
| 61 | #define PRED_PARAMS( z, m, dummy ) BOOST_PP_COMMA_IF( m ) BOOST_JOIN( arg, m ) |
| 62 | |
| 63 | #define ARG_INFO( z, m, dummy ) \ |
| 64 | , BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \ |
| 65 | , &static_cast<const unit_test::lazy_ostream&>(unit_test::lazy_ostream::instance() \ |
| 66 | << ::boost::test_tools::tt_detail::print_helper( BOOST_JOIN( arg, m ) )) \ |
| 67 | /**/ |
| 68 | |
| 69 | #define IMPL_FRWD( z, n, dummy ) \ |
| 70 | template<typename Pred \ |
| 71 | BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), TEMPL_PARAMS, _ )> \ |
| 72 | inline bool \ |
| 73 | check_frwd( Pred P, unit_test::lazy_ostream const& assertion_descr, \ |
| 74 | const_string file_name, std::size_t line_num, \ |
| 75 | tool_level tl, check_type ct \ |
| 76 | BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), FUNC_PARAMS, _ ) \ |
| 77 | ) \ |
| 78 | { \ |
| 79 | return \ |
| 80 | report_assertion( P( BOOST_PP_REPEAT_ ## z(BOOST_PP_ADD(n, 1), PRED_PARAMS,_) ),\ |
| 81 | assertion_descr, file_name, line_num, tl, ct, \ |
| 82 | BOOST_PP_ADD( n, 1 ) \ |
| 83 | BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), ARG_INFO, _ ) \ |
| 84 | ); \ |
| 85 | } \ |
| 86 | /**/ |
| 87 | |
| 88 | #ifndef BOOST_TEST_MAX_PREDICATE_ARITY |
| 89 | #define BOOST_TEST_MAX_PREDICATE_ARITY 5 |
| 90 | #endif |
| 91 | |
| 92 | BOOST_PP_REPEAT( BOOST_TEST_MAX_PREDICATE_ARITY, IMPL_FRWD, _ ) |
| 93 | |
| 94 | #undef TEMPL_PARAMS |
| 95 | #undef FUNC_PARAMS |
| 96 | #undef PRED_INFO |
| 97 | #undef ARG_INFO |
| 98 | #undef IMPL_FRWD |
| 99 | |
| 100 | #endif |
| 101 | |
| 102 | //____________________________________________________________________________// |
| 103 | |
| 104 | template <class Left, class Right> |
| 105 | inline assertion_result equal_impl( Left const& left, Right const& right ) |
| 106 | { |
| 107 | return left == right; |
| 108 | } |
| 109 | |
| 110 | //____________________________________________________________________________// |
| 111 | |
| 112 | inline assertion_result equal_impl( char* left, char const* right ) { return equal_impl( left: static_cast<char const*>(left), right: static_cast<char const*>(right) ); } |
| 113 | inline assertion_result equal_impl( char const* left, char* right ) { return equal_impl( left: static_cast<char const*>(left), right: static_cast<char const*>(right) ); } |
| 114 | inline assertion_result equal_impl( char* left, char* right ) { return equal_impl( left: static_cast<char const*>(left), right: static_cast<char const*>(right) ); } |
| 115 | |
| 116 | #if !defined( BOOST_NO_CWCHAR ) |
| 117 | BOOST_TEST_DECL assertion_result equal_impl( wchar_t const* left, wchar_t const* right ); |
| 118 | inline assertion_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( left: static_cast<wchar_t const*>(left), right: static_cast<wchar_t const*>(right) ); } |
| 119 | inline assertion_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( left: static_cast<wchar_t const*>(left), right: static_cast<wchar_t const*>(right) ); } |
| 120 | inline assertion_result equal_impl( wchar_t* left, wchar_t* right ) { return equal_impl( left: static_cast<wchar_t const*>(left), right: static_cast<wchar_t const*>(right) ); } |
| 121 | #endif |
| 122 | |
| 123 | //____________________________________________________________________________// |
| 124 | |
| 125 | struct equal_impl_frwd { |
| 126 | template <typename Left, typename Right> |
| 127 | inline assertion_result |
| 128 | call_impl( Left const& left, Right const& right, mpl::false_ ) const |
| 129 | { |
| 130 | return equal_impl( left, right ); |
| 131 | } |
| 132 | |
| 133 | template <typename Left, typename Right> |
| 134 | inline assertion_result |
| 135 | call_impl( Left const& left, Right const& right, mpl::true_ ) const |
| 136 | { |
| 137 | return (*this)( right, &left[0] ); |
| 138 | } |
| 139 | |
| 140 | template <typename Left, typename Right> |
| 141 | inline assertion_result |
| 142 | operator()( Left const& left, Right const& right ) const |
| 143 | { |
| 144 | typedef typename is_array<Left>::type left_is_array; |
| 145 | return call_impl( left, right, left_is_array() ); |
| 146 | } |
| 147 | }; |
| 148 | |
| 149 | //____________________________________________________________________________// |
| 150 | |
| 151 | struct ne_impl { |
| 152 | template <class Left, class Right> |
| 153 | assertion_result operator()( Left const& left, Right const& right ) |
| 154 | { |
| 155 | return !equal_impl_frwd()( left, right ); |
| 156 | } |
| 157 | }; |
| 158 | |
| 159 | //____________________________________________________________________________// |
| 160 | |
| 161 | struct lt_impl { |
| 162 | template <class Left, class Right> |
| 163 | assertion_result operator()( Left const& left, Right const& right ) |
| 164 | { |
| 165 | return left < right; |
| 166 | } |
| 167 | }; |
| 168 | |
| 169 | //____________________________________________________________________________// |
| 170 | |
| 171 | struct le_impl { |
| 172 | template <class Left, class Right> |
| 173 | assertion_result operator()( Left const& left, Right const& right ) |
| 174 | { |
| 175 | return left <= right; |
| 176 | } |
| 177 | }; |
| 178 | |
| 179 | //____________________________________________________________________________// |
| 180 | |
| 181 | struct gt_impl { |
| 182 | template <class Left, class Right> |
| 183 | assertion_result operator()( Left const& left, Right const& right ) |
| 184 | { |
| 185 | return left > right; |
| 186 | } |
| 187 | }; |
| 188 | |
| 189 | //____________________________________________________________________________// |
| 190 | |
| 191 | struct ge_impl { |
| 192 | template <class Left, class Right> |
| 193 | assertion_result operator()( Left const& left, Right const& right ) |
| 194 | { |
| 195 | return left >= right; |
| 196 | } |
| 197 | }; |
| 198 | |
| 199 | //____________________________________________________________________________// |
| 200 | |
| 201 | struct equal_coll_impl { |
| 202 | template <typename Left, typename Right> |
| 203 | assertion_result operator()( Left left_begin, Left left_end, Right right_begin, Right right_end ) |
| 204 | { |
| 205 | assertion_result pr( true ); |
| 206 | std::size_t pos = 0; |
| 207 | |
| 208 | for( ; left_begin != left_end && right_begin != right_end; ++left_begin, ++right_begin, ++pos ) { |
| 209 | if( *left_begin != *right_begin ) { |
| 210 | pr = false; |
| 211 | pr.message() << "\nMismatch at position " << pos << ": " |
| 212 | << ::boost::test_tools::tt_detail::print_helper(*left_begin) |
| 213 | << " != " |
| 214 | << ::boost::test_tools::tt_detail::print_helper(*right_begin); |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | if( left_begin != left_end ) { |
| 219 | std::size_t r_size = pos; |
| 220 | while( left_begin != left_end ) { |
| 221 | ++pos; |
| 222 | ++left_begin; |
| 223 | } |
| 224 | |
| 225 | pr = false; |
| 226 | pr.message() << "\nCollections size mismatch: " << pos << " != " << r_size; |
| 227 | } |
| 228 | |
| 229 | if( right_begin != right_end ) { |
| 230 | std::size_t l_size = pos; |
| 231 | while( right_begin != right_end ) { |
| 232 | ++pos; |
| 233 | ++right_begin; |
| 234 | } |
| 235 | |
| 236 | pr = false; |
| 237 | pr.message() << "\nCollections size mismatch: " << l_size << " != " << pos; |
| 238 | } |
| 239 | |
| 240 | return pr; |
| 241 | } |
| 242 | }; |
| 243 | |
| 244 | //____________________________________________________________________________// |
| 245 | |
| 246 | struct bitwise_equal_impl { |
| 247 | template <class Left, class Right> |
| 248 | assertion_result operator()( Left const& left, Right const& right ) |
| 249 | { |
| 250 | assertion_result pr( true ); |
| 251 | |
| 252 | std::size_t left_bit_size = sizeof(Left)*CHAR_BIT; |
| 253 | std::size_t right_bit_size = sizeof(Right)*CHAR_BIT; |
| 254 | |
| 255 | static Left const leftOne( 1 ); |
| 256 | static Right const rightOne( 1 ); |
| 257 | |
| 258 | std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size; |
| 259 | |
| 260 | for( std::size_t counter = 0; counter < total_bits; ++counter ) { |
| 261 | if( ( left & ( leftOne << counter ) ) != ( right & ( rightOne << counter ) ) ) { |
| 262 | pr = false; |
| 263 | pr.message() << "\nMismatch at position " << counter; |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | if( left_bit_size != right_bit_size ) { |
| 268 | pr = false; |
| 269 | pr.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size; |
| 270 | } |
| 271 | |
| 272 | return pr; |
| 273 | } |
| 274 | }; |
| 275 | |
| 276 | //____________________________________________________________________________// |
| 277 | |
| 278 | template<typename FPT1, typename FPT2> |
| 279 | struct comp_supertype { |
| 280 | // deduce "better" type from types of arguments being compared |
| 281 | // if one type is floating and the second integral we use floating type and |
| 282 | // value of integral type is promoted to the floating. The same for float and double |
| 283 | // But we don't want to compare two values of integral types using this tool. |
| 284 | typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype type; |
| 285 | BOOST_STATIC_ASSERT_MSG( !is_integral<type>::value, "Only floating-point types can be compared!" ); |
| 286 | }; |
| 287 | |
| 288 | } // namespace tt_detail |
| 289 | |
| 290 | namespace fpc = math::fpc; |
| 291 | |
| 292 | // ************************************************************************** // |
| 293 | // ************** check_is_close ************** // |
| 294 | // ************************************************************************** // |
| 295 | |
| 296 | struct BOOST_TEST_DECL check_is_close_t { |
| 297 | // Public typedefs |
| 298 | typedef assertion_result result_type; |
| 299 | |
| 300 | template<typename FPT1, typename FPT2, typename ToleranceType> |
| 301 | assertion_result |
| 302 | operator()( FPT1 left, FPT2 right, ToleranceType tolerance ) const |
| 303 | { |
| 304 | fpc::close_at_tolerance<typename tt_detail::comp_supertype<FPT1,FPT2>::type> pred( tolerance, fpc::FPC_STRONG ); |
| 305 | |
| 306 | assertion_result ar( pred( left, right ) ); |
| 307 | |
| 308 | if( !ar ) |
| 309 | ar.message() << pred.tested_rel_diff(); |
| 310 | |
| 311 | return ar; |
| 312 | } |
| 313 | }; |
| 314 | |
| 315 | //____________________________________________________________________________// |
| 316 | |
| 317 | template<typename FPT1, typename FPT2, typename ToleranceType> |
| 318 | inline assertion_result |
| 319 | check_is_close( FPT1 left, FPT2 right, ToleranceType tolerance ) |
| 320 | { |
| 321 | return check_is_close_t()( left, right, tolerance ); |
| 322 | } |
| 323 | |
| 324 | //____________________________________________________________________________// |
| 325 | |
| 326 | // ************************************************************************** // |
| 327 | // ************** check_is_small ************** // |
| 328 | // ************************************************************************** // |
| 329 | |
| 330 | struct BOOST_TEST_DECL check_is_small_t { |
| 331 | // Public typedefs |
| 332 | typedef bool result_type; |
| 333 | |
| 334 | template<typename FPT> |
| 335 | bool |
| 336 | operator()( FPT fpv, FPT tolerance ) const |
| 337 | { |
| 338 | return fpc::is_small( fpv, tolerance ); |
| 339 | } |
| 340 | }; |
| 341 | |
| 342 | //____________________________________________________________________________// |
| 343 | |
| 344 | template<typename FPT> |
| 345 | inline bool |
| 346 | check_is_small( FPT fpv, FPT tolerance ) |
| 347 | { |
| 348 | return fpc::is_small( fpv, tolerance ); |
| 349 | } |
| 350 | |
| 351 | //____________________________________________________________________________// |
| 352 | |
| 353 | } // namespace test_tools |
| 354 | } // namespace boost |
| 355 | |
| 356 | #include <boost/test/detail/enable_warnings.hpp> |
| 357 | |
| 358 | #endif // BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER |
| 359 | |