Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:14

0001 #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP
0002 #define BOOST_CORE_LIGHTWEIGHT_TEST_HPP
0003 
0004 // MS compatible compilers support #pragma once
0005 
0006 #if defined(_MSC_VER)
0007 # pragma once
0008 #endif
0009 
0010 //
0011 //  boost/core/lightweight_test.hpp - lightweight test library
0012 //
0013 //  Copyright (c) 2002, 2009, 2014 Peter Dimov
0014 //  Copyright (2) Beman Dawes 2010, 2011
0015 //  Copyright (3) Ion Gaztanaga 2013
0016 //
0017 //  Copyright 2018 Glen Joseph Fernandes
0018 //  (glenjofe@gmail.com)
0019 //
0020 //  Distributed under the Boost Software License, Version 1.0.
0021 //  See accompanying file LICENSE_1_0.txt or copy at
0022 //  http://www.boost.org/LICENSE_1_0.txt
0023 //
0024 
0025 #include <boost/core/detail/lwt_unattended.hpp>
0026 #include <boost/current_function.hpp>
0027 #include <boost/config.hpp>
0028 #include <exception>
0029 #include <iostream>
0030 #include <iterator>
0031 #include <string>
0032 #include <cstdlib>
0033 #include <cstring>
0034 #include <cstddef>
0035 #include <cctype>
0036 
0037 //  IDE's like Visual Studio perform better if output goes to std::cout or
0038 //  some other stream, so allow user to configure output stream:
0039 #ifndef BOOST_LIGHTWEIGHT_TEST_OSTREAM
0040 # define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cerr
0041 #endif
0042 
0043 namespace boost
0044 {
0045 namespace detail
0046 {
0047 
0048 class test_result
0049 {
0050 public:
0051 
0052     test_result(): report_( false ), errors_( 0 )
0053     {
0054         core::detail::lwt_unattended();
0055     }
0056 
0057     ~test_result()
0058     {
0059         if( !report_ )
0060         {
0061             BOOST_LIGHTWEIGHT_TEST_OSTREAM << "main() should return report_errors()" << std::endl;
0062             std::abort();
0063         }
0064     }
0065 
0066     int& errors()
0067     {
0068         return errors_;
0069     }
0070 
0071     void done()
0072     {
0073         report_ = true;
0074     }
0075 
0076 private:
0077 
0078     bool report_;
0079     int errors_;
0080 };
0081 
0082 inline test_result& test_results()
0083 {
0084     static test_result instance;
0085     return instance;
0086 }
0087 
0088 inline int& test_errors()
0089 {
0090     return test_results().errors();
0091 }
0092 
0093 inline bool test_impl(char const * expr, char const * file, int line, char const * function, bool v)
0094 {
0095     if( v )
0096     {
0097         test_results();
0098         return true;
0099     }
0100     else
0101     {
0102         BOOST_LIGHTWEIGHT_TEST_OSTREAM
0103           << file << "(" << line << "): test '" << expr << "' failed in function '"
0104           << function << "'" << std::endl;
0105         ++test_results().errors();
0106         return false;
0107     }
0108 }
0109 
0110 inline void error_impl(char const * msg, char const * file, int line, char const * function)
0111 {
0112     BOOST_LIGHTWEIGHT_TEST_OSTREAM
0113       << file << "(" << line << "): " << msg << " in function '"
0114       << function << "'" << std::endl;
0115     ++test_results().errors();
0116 }
0117 
0118 inline void throw_failed_impl(const char* expr, char const * excep, char const * file, int line, char const * function)
0119 {
0120    BOOST_LIGHTWEIGHT_TEST_OSTREAM
0121     << file << "(" << line << "): expression '" << expr << "' did not throw exception '" << excep << "' in function '"
0122     << function << "'" << std::endl;
0123    ++test_results().errors();
0124 }
0125 
0126 inline void no_throw_failed_impl(const char* expr, const char* file, int line, const char* function)
0127 {
0128     BOOST_LIGHTWEIGHT_TEST_OSTREAM
0129         << file << "(" << line << "): expression '" << expr << "' threw an exception in function '"
0130         << function << "'" << std::endl;
0131    ++test_results().errors();
0132 }
0133 
0134 inline void no_throw_failed_impl(const char* expr, const char* what, const char* file, int line, const char* function)
0135 {
0136     BOOST_LIGHTWEIGHT_TEST_OSTREAM
0137         << file << "(" << line << "): expression '" << expr << "' threw an exception in function '"
0138         << function << "': " << what << std::endl;
0139    ++test_results().errors();
0140 }
0141 
0142 // In the comparisons below, it is possible that T and U are signed and unsigned integer types, which generates warnings in some compilers.
0143 // A cleaner fix would require common_type trait or some meta-programming, which would introduce a dependency on Boost.TypeTraits. To avoid
0144 // the dependency we just disable the warnings.
0145 #if defined(__clang__) && defined(__has_warning)
0146 # if __has_warning("-Wsign-compare")
0147 #  pragma clang diagnostic push
0148 #  pragma clang diagnostic ignored "-Wsign-compare"
0149 # endif
0150 #elif defined(_MSC_VER)
0151 # pragma warning(push)
0152 # pragma warning(disable: 4389)
0153 #elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
0154 # pragma GCC diagnostic push
0155 # pragma GCC diagnostic ignored "-Wsign-compare"
0156 #endif
0157 
0158 // specialize test output for char pointers to avoid printing as cstring
0159 template <class T> inline const T& test_output_impl(const T& v) { return v; }
0160 inline const void* test_output_impl(const char* v) { return v; }
0161 inline const void* test_output_impl(const unsigned char* v) { return v; }
0162 inline const void* test_output_impl(const signed char* v) { return v; }
0163 inline const void* test_output_impl(char* v) { return v; }
0164 inline const void* test_output_impl(unsigned char* v) { return v; }
0165 inline const void* test_output_impl(signed char* v) { return v; }
0166 template<class T> inline const void* test_output_impl(T volatile* v) { return const_cast<T*>(v); }
0167 
0168 #if !defined( BOOST_NO_CXX11_NULLPTR )
0169 inline const void* test_output_impl(std::nullptr_t) { return nullptr; }
0170 #endif
0171 
0172 // print chars as numeric
0173 
0174 inline int test_output_impl( signed char const& v ) { return v; }
0175 inline unsigned test_output_impl( unsigned char const& v ) { return v; }
0176 
0177 // Whether wchar_t is signed is implementation-defined
0178 
0179 template<bool Signed> struct lwt_long_type {};
0180 template<> struct lwt_long_type<true> { typedef long type; };
0181 template<> struct lwt_long_type<false> { typedef unsigned long type; };
0182 
0183 inline lwt_long_type<(static_cast<wchar_t>(-1) < static_cast<wchar_t>(0))>::type test_output_impl( wchar_t const& v ) { return v; }
0184 
0185 #if !defined( BOOST_NO_CXX11_CHAR16_T )
0186 inline unsigned long test_output_impl( char16_t const& v ) { return v; }
0187 #endif
0188 
0189 #if !defined( BOOST_NO_CXX11_CHAR32_T )
0190 inline unsigned long test_output_impl( char32_t const& v ) { return v; }
0191 #endif
0192 
0193 inline std::string test_output_impl( char const& v )
0194 {
0195     if( std::isprint( static_cast<unsigned char>( v ) ) )
0196     {
0197         return std::string( 1, v );
0198     }
0199     else
0200     {
0201         static const char char_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
0202         char buffer[ 4 ];
0203         buffer[ 0 ] = '\\';
0204         buffer[ 1 ] = 'x';
0205         buffer[ 2 ] = char_table[ (static_cast<unsigned char>( v ) >> 4u) & 0x0f ];
0206         buffer[ 3 ] = char_table[ static_cast<unsigned char>( v ) & 0x0f ];
0207 
0208         return std::string( buffer, 4u );
0209     }
0210 }
0211 
0212 // predicates
0213 
0214 struct lw_test_eq
0215 {
0216     template <typename T, typename U>
0217     bool operator()(const T& t, const U& u) const { return t == u; }
0218 };
0219 
0220 struct lw_test_ne
0221 {
0222     template <typename T, typename U>
0223     bool operator()(const T& t, const U& u) const { return t != u; }
0224 };
0225 
0226 struct lw_test_lt
0227 {
0228     template <typename T, typename U>
0229     bool operator()(const T& t, const U& u) const { return t < u; }
0230 };
0231 
0232 struct lw_test_le
0233 {
0234     template <typename T, typename U>
0235     bool operator()(const T& t, const U& u) const { return t <= u; }
0236 };
0237 
0238 struct lw_test_gt
0239 {
0240     template <typename T, typename U>
0241     bool operator()(const T& t, const U& u) const { return t > u; }
0242 };
0243 
0244 struct lw_test_ge
0245 {
0246     template <typename T, typename U>
0247     bool operator()(const T& t, const U& u) const { return t >= u; }
0248 };
0249 
0250 // lwt_predicate_name
0251 
0252 template<class T> char const * lwt_predicate_name( T const& )
0253 {
0254     return "~=";
0255 }
0256 
0257 inline char const * lwt_predicate_name( lw_test_eq const& )
0258 {
0259     return "==";
0260 }
0261 
0262 inline char const * lwt_predicate_name( lw_test_ne const& )
0263 {
0264     return "!=";
0265 }
0266 
0267 inline char const * lwt_predicate_name( lw_test_lt const& )
0268 {
0269     return "<";
0270 }
0271 
0272 inline char const * lwt_predicate_name( lw_test_le const& )
0273 {
0274     return "<=";
0275 }
0276 
0277 inline char const * lwt_predicate_name( lw_test_gt const& )
0278 {
0279     return ">";
0280 }
0281 
0282 inline char const * lwt_predicate_name( lw_test_ge const& )
0283 {
0284     return ">=";
0285 }
0286 
0287 //
0288 
0289 template<class BinaryPredicate, class T, class U>
0290 inline bool test_with_impl(BinaryPredicate pred, char const * expr1, char const * expr2,
0291                            char const * file, int line, char const * function,
0292                            T const & t, U const & u)
0293 {
0294     if( pred(t, u) )
0295     {
0296         test_results();
0297         return true;
0298     }
0299     else
0300     {
0301         BOOST_LIGHTWEIGHT_TEST_OSTREAM
0302             << file << "(" << line << "): test '" << expr1 << " " << lwt_predicate_name(pred) << " " << expr2
0303             << "' ('" << test_output_impl(t) << "' " << lwt_predicate_name(pred) << " '" << test_output_impl(u)
0304             << "') failed in function '" << function << "'" << std::endl;
0305         ++test_results().errors();
0306         return false;
0307     }
0308 }
0309 
0310 inline bool test_cstr_eq_impl( char const * expr1, char const * expr2,
0311   char const * file, int line, char const * function, char const * const t, char const * const u )
0312 {
0313     if( std::strcmp(t, u) == 0 )
0314     {
0315         test_results();
0316         return true;
0317     }
0318     else
0319     {
0320         BOOST_LIGHTWEIGHT_TEST_OSTREAM
0321             << file << "(" << line << "): test '" << expr1 << " == " << expr2 << "' ('" << t
0322             << "' == '" << u << "') failed in function '" << function << "'" << std::endl;
0323         ++test_results().errors();
0324         return false;
0325     }
0326 }
0327 
0328 inline bool test_cstr_ne_impl( char const * expr1, char const * expr2,
0329   char const * file, int line, char const * function, char const * const t, char const * const u )
0330 {
0331     if( std::strcmp(t, u) != 0 )
0332     {
0333         test_results();
0334         return true;
0335     }
0336     else
0337     {
0338         BOOST_LIGHTWEIGHT_TEST_OSTREAM
0339             << file << "(" << line << "): test '" << expr1 << " != " << expr2 << "' ('" << t
0340             << "' != '" << u << "') failed in function '" << function << "'" << std::endl;
0341         ++test_results().errors();
0342         return false;
0343     }
0344 }
0345 
0346 template<class FormattedOutputFunction, class InputIterator1, class InputIterator2>
0347 bool test_all_eq_impl(FormattedOutputFunction& output,
0348                       char const * file, int line, char const * function,
0349                       InputIterator1 first_begin, InputIterator1 first_end,
0350                       InputIterator2 second_begin, InputIterator2 second_end)
0351 {
0352     InputIterator1 first_it = first_begin;
0353     InputIterator2 second_it = second_begin;
0354     typename std::iterator_traits<InputIterator1>::difference_type first_index = 0;
0355     typename std::iterator_traits<InputIterator2>::difference_type second_index = 0;
0356     std::size_t error_count = 0;
0357     const std::size_t max_count = 8;
0358     do
0359     {
0360         while ((first_it != first_end) && (second_it != second_end) && (*first_it == *second_it))
0361         {
0362             ++first_it;
0363             ++second_it;
0364             ++first_index;
0365             ++second_index;
0366         }
0367         if ((first_it == first_end) || (second_it == second_end))
0368         {
0369             break; // do-while
0370         }
0371         if (error_count == 0)
0372         {
0373             output << file << "(" << line << "): Container contents differ in function '" << function << "':";
0374         }
0375         else if (error_count >= max_count)
0376         {
0377             output << " ...";
0378             break;
0379         }
0380         output << " [" << first_index << "] '" << test_output_impl(*first_it) << "' != '" << test_output_impl(*second_it) << "'";
0381         ++first_it;
0382         ++second_it;
0383         ++first_index;
0384         ++second_index;
0385         ++error_count;
0386     } while (first_it != first_end);
0387 
0388     first_index += std::distance(first_it, first_end);
0389     second_index += std::distance(second_it, second_end);
0390     if (first_index != second_index)
0391     {
0392         if (error_count == 0)
0393         {
0394             output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")";
0395         }
0396         else
0397         {
0398             output << " [*] size(" << first_index << ") != size(" << second_index << ")";
0399         }
0400         ++error_count;
0401     }
0402 
0403     if (error_count == 0)
0404     {
0405         test_results();
0406         return true;
0407     }
0408     else
0409     {
0410         output << std::endl;
0411         ++test_results().errors();
0412         return false;
0413     }
0414 }
0415 
0416 template<class FormattedOutputFunction, class InputIterator1, class InputIterator2, typename BinaryPredicate>
0417 bool test_all_with_impl(FormattedOutputFunction& output,
0418                         char const * file, int line, char const * function,
0419                         InputIterator1 first_begin, InputIterator1 first_end,
0420                         InputIterator2 second_begin, InputIterator2 second_end,
0421                         BinaryPredicate predicate)
0422 {
0423     InputIterator1 first_it = first_begin;
0424     InputIterator2 second_it = second_begin;
0425     typename std::iterator_traits<InputIterator1>::difference_type first_index = 0;
0426     typename std::iterator_traits<InputIterator2>::difference_type second_index = 0;
0427     std::size_t error_count = 0;
0428     const std::size_t max_count = 8;
0429     do
0430     {
0431         while ((first_it != first_end) && (second_it != second_end) && predicate(*first_it, *second_it))
0432         {
0433             ++first_it;
0434             ++second_it;
0435             ++first_index;
0436             ++second_index;
0437         }
0438         if ((first_it == first_end) || (second_it == second_end))
0439         {
0440             break; // do-while
0441         }
0442         if (error_count == 0)
0443         {
0444             output << file << "(" << line << "): Container contents differ in function '" << function << "':";
0445         }
0446         else if (error_count >= max_count)
0447         {
0448             output << " ...";
0449             break;
0450         }
0451         output << " [" << first_index << "]";
0452         ++first_it;
0453         ++second_it;
0454         ++first_index;
0455         ++second_index;
0456         ++error_count;
0457     } while (first_it != first_end);
0458 
0459     first_index += std::distance(first_it, first_end);
0460     second_index += std::distance(second_it, second_end);
0461     if (first_index != second_index)
0462     {
0463         if (error_count == 0)
0464         {
0465             output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")";
0466         }
0467         else
0468         {
0469             output << " [*] size(" << first_index << ") != size(" << second_index << ")";
0470         }
0471         ++error_count;
0472     }
0473 
0474     if (error_count == 0)
0475     {
0476         test_results();
0477         return true;
0478     }
0479     else
0480     {
0481         output << std::endl;
0482         ++test_results().errors();
0483         return false;
0484     }
0485 }
0486 
0487 #if defined(__clang__) && defined(__has_warning)
0488 # if __has_warning("-Wsign-compare")
0489 #  pragma clang diagnostic pop
0490 # endif
0491 #elif defined(_MSC_VER)
0492 # pragma warning(pop)
0493 #elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
0494 # pragma GCC diagnostic pop
0495 #endif
0496 
0497 } // namespace detail
0498 
0499 inline int report_errors()
0500 {
0501     boost::detail::test_result& result = boost::detail::test_results();
0502     result.done();
0503 
0504     int errors = result.errors();
0505 
0506     if( errors == 0 )
0507     {
0508         BOOST_LIGHTWEIGHT_TEST_OSTREAM
0509           << "No errors detected." << std::endl;
0510     }
0511     else
0512     {
0513         BOOST_LIGHTWEIGHT_TEST_OSTREAM
0514           << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl;
0515     }
0516 
0517     // `return report_errors();` from main only supports 8 bit exit codes
0518     return errors < 256? errors: 255;
0519 }
0520 
0521 namespace core
0522 {
0523 
0524 inline void lwt_init()
0525 {
0526     boost::detail::test_results();
0527 }
0528 
0529 } // namespace core
0530 } // namespace boost
0531 
0532 #define BOOST_TEST(expr) ( ::boost::detail::test_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, (expr)? true: false) )
0533 #define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr))
0534 
0535 #define BOOST_ERROR(msg) ( ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
0536 
0537 #define BOOST_TEST_WITH(expr1,expr2,predicate) ( ::boost::detail::test_with_impl(predicate, #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0538 
0539 #define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_eq(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0540 #define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_ne(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0541 
0542 #define BOOST_TEST_LT(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_lt(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0543 #define BOOST_TEST_LE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_le(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0544 #define BOOST_TEST_GT(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_gt(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0545 #define BOOST_TEST_GE(expr1,expr2) ( ::boost::detail::test_with_impl(::boost::detail::lw_test_ge(), #expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0546 
0547 #define BOOST_TEST_CSTR_EQ(expr1,expr2) ( ::boost::detail::test_cstr_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0548 #define BOOST_TEST_CSTR_NE(expr1,expr2) ( ::boost::detail::test_cstr_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
0549 
0550 #define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) ( ::boost::detail::test_all_eq_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2) )
0551 #define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) )
0552 
0553 #ifndef BOOST_NO_EXCEPTIONS
0554    #define BOOST_TEST_THROWS( EXPR, EXCEP )                           \
0555       try {                                                           \
0556          EXPR;                                                        \
0557          ::boost::detail::throw_failed_impl                           \
0558          (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
0559       }                                                               \
0560       catch(EXCEP const&) {                                           \
0561          ::boost::detail::test_results();                             \
0562       }                                                               \
0563       catch(...) {                                                    \
0564          ::boost::detail::throw_failed_impl                           \
0565          (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
0566       }                                                               \
0567    //
0568 #else
0569    #define BOOST_TEST_THROWS( EXPR, EXCEP )
0570 #endif
0571 
0572 #ifndef BOOST_NO_EXCEPTIONS
0573 #  define BOOST_TEST_NO_THROW(EXPR)                                    \
0574     try {                                                              \
0575         EXPR;                                                          \
0576     } catch (const std::exception& e) {                                \
0577         ::boost::detail::no_throw_failed_impl                          \
0578         (#EXPR, e.what(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
0579     } catch (...) {                                                    \
0580         ::boost::detail::no_throw_failed_impl                          \
0581         (#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION);           \
0582     }
0583     //
0584 #else
0585 #  define BOOST_TEST_NO_THROW(EXPR) { EXPR; }
0586 #endif
0587 
0588 #endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP