test_helpers.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright (C) 2003, Fernando Luis Cacciola Carballal.
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. //
  8. // NOTE: This file is intended to be used ONLY by the test files
  9. // from the Numeric Conversions Library
  10. //
  11. //
  12. #include <cmath>
  13. #include "boost/limits.hpp"
  14. #include "boost/utility.hpp"
  15. #include "boost/test/included/test_exec_monitor.hpp"
  16. // Convenience macros to help with compilers which don't parse
  17. // explicit template function instantiations (MSVC6)
  18. #define MATCH_FNTPL_ARG(t) t const*
  19. #define SET_FNTPL_ARG(t) (static_cast< t const* >(0))
  20. //
  21. // *Minimal* example of a User Defined Numeric Type
  22. //
  23. //
  24. namespace MyUDT
  25. {
  26. template<class T>
  27. struct UDT
  28. {
  29. typedef T builtin_type ;
  30. UDT ( T v_ ) : v (v_) {}
  31. T to_builtin() const { return v ; }
  32. friend bool operator == ( UDT const& lhs, UDT const& rhs )
  33. { return lhs.to_builtin() == rhs.to_builtin() ; }
  34. // NOTE: This operator is *required* by the Numeric Conversion Library
  35. // if Turnc<> is used as the Float2IntRounder policy.
  36. friend bool operator < ( UDT const& lhs, UDT const& rhs )
  37. { return lhs.to_builtin() < rhs.to_builtin() ; }
  38. friend std::ostream& operator << ( std::ostream& os, UDT const& n )
  39. { return os << n.to_builtin() ; }
  40. T v ;
  41. } ;
  42. typedef UDT<int> MyInt ;
  43. typedef UDT<double> MyFloat ;
  44. //
  45. // The Float2IntRounder policies *require* a visible 'ceil' or 'floor' math function
  46. // with standard semantics.
  47. // In a conformant compiler, ADL can pick these functions even if they are defined
  48. // within a user namespace, as below.
  49. //
  50. inline MyInt ceil ( MyInt const& x ) { return x ; }
  51. inline MyInt floor ( MyInt const& x ) { return x ; }
  52. inline MyFloat floor ( MyFloat const& x )
  53. {
  54. #if !defined(BOOST_NO_STDC_NAMESPACE)
  55. return MyFloat ( std::floor(x.to_builtin()) ) ;
  56. #else
  57. return MyFloat ( ::floor(x.to_builtin()) ) ;
  58. #endif
  59. }
  60. inline MyFloat ceil ( MyFloat const& x )
  61. {
  62. #if !defined(BOOST_NO_STDC_NAMESPACE)
  63. return MyFloat ( std::ceil(x.to_builtin()) ) ;
  64. #else
  65. return MyFloat ( ::ceil(x.to_builtin()) ) ;
  66. #endif
  67. }
  68. } // namespace MyUDT
  69. //
  70. // The Numeric Conversion Library *requires* User Defined Numeric Types
  71. // to properly specialize std::numeric_limits<>
  72. //
  73. namespace std
  74. {
  75. template<>
  76. class numeric_limits<MyUDT::MyInt> : public numeric_limits<int>
  77. {
  78. public :
  79. BOOST_STATIC_CONSTANT(bool, is_specialized = false);
  80. } ;
  81. template<>
  82. class numeric_limits<MyUDT::MyFloat> : public numeric_limits<double>
  83. {
  84. public :
  85. BOOST_STATIC_CONSTANT(bool, is_specialized = false);
  86. } ;
  87. } // namespace std
  88. //
  89. // The functions floor and ceil defined within namespace MyUDT
  90. // should be found by koenig loopkup, but some compilers don't do it right
  91. // so we inyect them into namespace std so ordinary overload resolution
  92. // can found them.
  93. #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || defined(__BORLANDC__) || defined(__GNUC__)
  94. namespace std {
  95. using MyUDT::floor ;
  96. using MyUDT::ceil ;
  97. } // namespace std
  98. #endif
  99. std::string to_string( bool arg )
  100. {
  101. return arg ? "true" : "false" ;
  102. }
  103. std::string to_string( ... ) { throw std::runtime_error("to_string() called with wrong type!") ; }
  104. //
  105. // This is used to print 'char' values as numbers instead of characters.
  106. //
  107. template<class T> struct printable_number_type { typedef T type ; } ;
  108. template<> struct printable_number_type<signed char> { typedef int type ; } ;
  109. template<> struct printable_number_type<unsigned char> { typedef unsigned type ; } ;
  110. template<> struct printable_number_type<char> { typedef int type ; } ;
  111. template<class T>
  112. inline
  113. typename printable_number_type<T>::type
  114. printable( T n ) { return n ; }
  115. //
  116. ///////////////////////////////////////////////////////////////////////////////////////////////