tolerance_manip.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. //! @file
  8. //! @brief Floating point comparison tolerance manipulators
  9. //!
  10. //! This file defines several manipulators for floating point comparison. These
  11. //! manipulators are intended to be used with BOOST_TEST.
  12. // ***************************************************************************
  13. #ifndef BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
  14. #define BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
  15. // Boost Test
  16. #include <boost/test/tools/detail/fwd.hpp>
  17. #include <boost/test/tools/detail/indirections.hpp>
  18. #include <boost/test/utils/lazy_ostream.hpp>
  19. #include <boost/test/tools/fpc_tolerance.hpp>
  20. #include <boost/test/tools/floating_point_comparison.hpp>
  21. #include <ostream>
  22. #include <boost/test/detail/suppress_warnings.hpp>
  23. //____________________________________________________________________________//
  24. namespace boost {
  25. namespace test_tools {
  26. namespace tt_detail {
  27. // ************************************************************************** //
  28. // ************** fpc tolerance manipulator ************** //
  29. // ************************************************************************** //
  30. //! Tolerance manipulator, not to be used directly
  31. //! This is not a terminal of the expression
  32. template<typename FPT>
  33. struct tolerance_manip {
  34. explicit tolerance_manip( FPT const & tol ) : m_value( tol ) {}
  35. FPT m_value;
  36. };
  37. //____________________________________________________________________________//
  38. struct tolerance_manip_delay {};
  39. template<typename FPT>
  40. inline tolerance_manip<FPT>
  41. operator%( FPT v, tolerance_manip_delay const& )
  42. {
  43. BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
  44. "tolerance should be specified using a floating points type" );
  45. return tolerance_manip<FPT>( FPT(v / 100) );
  46. }
  47. template <typename FPT>
  48. struct tolerance_evaluation_context: assertion_evaluation_context {
  49. tolerance_evaluation_context(FPT tol)
  50. : assertion_evaluation_context( true ) // has report
  51. , m_tolerance_context(tol)
  52. {}
  53. local_fpc_tolerance<FPT> m_tolerance_context;
  54. };
  55. //____________________________________________________________________________//
  56. template<typename E, typename FPT>
  57. inline assertion_evaluate_t<E>
  58. operator<<(assertion_evaluate_t<E> const& ae, tolerance_manip<FPT> const& tol)
  59. {
  60. return ae.stack_context(
  61. typename assertion_evaluate_t<E>::context_holder(
  62. new tolerance_evaluation_context<FPT>( tol.m_value ))
  63. );
  64. }
  65. //____________________________________________________________________________//
  66. template<typename FPT>
  67. unit_test::lazy_ostream &
  68. operator<<( unit_test::lazy_ostream &o, tolerance_manip<FPT> const& ) { return o; }
  69. // needed for the lazy evaluation in lazy_ostream as for commutativity with other arguments
  70. template<typename FPT>
  71. std::ostream&
  72. operator<<( std::ostream& o, tolerance_manip<FPT> const& ) { return o; }
  73. //____________________________________________________________________________//
  74. template<typename FPT>
  75. inline assertion_type
  76. operator<<( assertion_type const& /*at*/, tolerance_manip<FPT> const& ) {
  77. return assertion_type(CHECK_BUILT_ASSERTION);
  78. }
  79. //____________________________________________________________________________//
  80. } // namespace tt_detail
  81. /*! Tolerance manipulator
  82. *
  83. * These functions return a manipulator that can be used in conjunction with BOOST_TEST
  84. * in order to specify the tolerance with which floating point comparisons are made.
  85. */
  86. template<typename FPT>
  87. inline tt_detail::tolerance_manip<FPT>
  88. tolerance( FPT v )
  89. {
  90. BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
  91. "tolerance only for floating points" );
  92. return tt_detail::tolerance_manip<FPT>( v );
  93. }
  94. //____________________________________________________________________________//
  95. //! @overload tolerance( FPT v )
  96. template<typename FPT>
  97. inline tt_detail::tolerance_manip<FPT>
  98. tolerance( fpc::percent_tolerance_t<FPT> v )
  99. {
  100. BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
  101. "tolerance only for floating points" );
  102. return tt_detail::tolerance_manip<FPT>( static_cast<FPT>(v.m_value / 100) );
  103. }
  104. //____________________________________________________________________________//
  105. //! @overload tolerance( FPT v )
  106. inline tt_detail::tolerance_manip_delay
  107. tolerance()
  108. {
  109. return tt_detail::tolerance_manip_delay();
  110. }
  111. //____________________________________________________________________________//
  112. } // namespace test_tools
  113. } // namespace boost
  114. #include <boost/test/detail/enable_warnings.hpp>
  115. #endif // BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER