| 3030 | namespace Detail { |
| 3031 | |
| 3032 | class Approx { |
| 3033 | private: |
| 3034 | bool equalityComparisonImpl(double other) const; |
| 3035 | // Validates the new margin (margin >= 0) |
| 3036 | // out-of-line to avoid including stdexcept in the header |
| 3037 | void setMargin(double margin); |
| 3038 | // Validates the new epsilon (0 < epsilon < 1) |
| 3039 | // out-of-line to avoid including stdexcept in the header |
| 3040 | void setEpsilon(double epsilon); |
| 3041 | |
| 3042 | public: |
| 3043 | explicit Approx ( double value ); |
| 3044 | |
| 3045 | static Approx custom(); |
| 3046 | |
| 3047 | Approx operator-() const; |
| 3048 | |
| 3049 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3050 | Approx operator()( T const& value ) { |
| 3051 | Approx approx( static_cast<double>(value) ); |
| 3052 | approx.m_epsilon = m_epsilon; |
| 3053 | approx.m_margin = m_margin; |
| 3054 | approx.m_scale = m_scale; |
| 3055 | return approx; |
| 3056 | } |
| 3057 | |
| 3058 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3059 | explicit Approx( T const& value ): Approx(static_cast<double>(value)) |
| 3060 | {} |
| 3061 | |
| 3062 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3063 | friend bool operator == ( const T& lhs, Approx const& rhs ) { |
| 3064 | auto lhs_v = static_cast<double>(lhs); |
| 3065 | return rhs.equalityComparisonImpl(lhs_v); |
| 3066 | } |
| 3067 | |
| 3068 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3069 | friend bool operator == ( Approx const& lhs, const T& rhs ) { |
| 3070 | return operator==( rhs, lhs ); |
| 3071 | } |
| 3072 | |
| 3073 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3074 | friend bool operator != ( T const& lhs, Approx const& rhs ) { |
| 3075 | return !operator==( lhs, rhs ); |
| 3076 | } |
| 3077 | |
| 3078 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3079 | friend bool operator != ( Approx const& lhs, T const& rhs ) { |
| 3080 | return !operator==( rhs, lhs ); |
| 3081 | } |
| 3082 | |
| 3083 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3084 | friend bool operator <= ( T const& lhs, Approx const& rhs ) { |
| 3085 | return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; |
| 3086 | } |
| 3087 | |
| 3088 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 3089 | friend bool operator <= ( Approx const& lhs, T const& rhs ) { |
nothing calls this directly
no outgoing calls
no test coverage detected