value_with_epsilon.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright (c) 2018 Andrey Semashev
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_ATOMIC_TESTS_VALUE_WITH_EPSILON_H_INCLUDED_
  7. #define BOOST_ATOMIC_TESTS_VALUE_WITH_EPSILON_H_INCLUDED_
  8. #include <limits>
  9. #include <iosfwd>
  10. template< typename T >
  11. class value_with_epsilon
  12. {
  13. private:
  14. T m_value;
  15. T m_epsilon;
  16. public:
  17. value_with_epsilon(T value, T epsilon) : m_value(value), m_epsilon(epsilon) {}
  18. T value() const
  19. {
  20. return m_value;
  21. }
  22. T epsilon() const
  23. {
  24. return m_epsilon;
  25. }
  26. bool equal(T value) const
  27. {
  28. return value >= (m_value - m_epsilon) && value <= (m_value + m_epsilon);
  29. }
  30. friend bool operator== (T left, value_with_epsilon< T > const& right)
  31. {
  32. return right.equal(left);
  33. }
  34. friend bool operator== (value_with_epsilon< T > const& left, T right)
  35. {
  36. return left.equal(right);
  37. }
  38. friend bool operator!= (T left, value_with_epsilon< T > const& right)
  39. {
  40. return !right.equal(left);
  41. }
  42. friend bool operator!= (value_with_epsilon< T > const& left, T right)
  43. {
  44. return !left.equal(right);
  45. }
  46. };
  47. template< typename Char, typename Traits, typename T >
  48. inline std::basic_ostream< Char, Traits >& operator<< (std::basic_ostream< Char, Traits >& strm, value_with_epsilon< T > const& val)
  49. {
  50. // Note: libstdc++ does not provide output operators for __float128. There may also be no operators for long double.
  51. // We don't use such floating point values in our tests where the cast would matter.
  52. strm << static_cast< double >(val.value()) << " (+/-" << static_cast< double >(val.epsilon()) << ")";
  53. return strm;
  54. }
  55. template< typename T, typename U >
  56. inline value_with_epsilon< T > approx(T value, U epsilon)
  57. {
  58. return value_with_epsilon< T >(value, static_cast< T >(epsilon));
  59. }
  60. template< typename T >
  61. inline value_with_epsilon< T > approx(T value)
  62. {
  63. return value_with_epsilon< T >(value, static_cast< T >(0.0000001));
  64. }
  65. #endif // BOOST_ATOMIC_TESTS_VALUE_WITH_EPSILON_H_INCLUDED_