| 1947 | namespace Detail { |
| 1948 | |
| 1949 | class Approx { |
| 1950 | private: |
| 1951 | bool equalityComparisonImpl(double other) const; |
| 1952 | |
| 1953 | public: |
| 1954 | explicit Approx(double value); |
| 1955 | |
| 1956 | static Approx custom(); |
| 1957 | |
| 1958 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1959 | Approx operator()(T const &value) { |
| 1960 | Approx approx(static_cast<double>(value)); |
| 1961 | approx.epsilon(m_epsilon); |
| 1962 | approx.margin(m_margin); |
| 1963 | approx.scale(m_scale); |
| 1964 | return approx; |
| 1965 | } |
| 1966 | |
| 1967 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1968 | explicit Approx(T const &value) : Approx(static_cast<double>(value)) { |
| 1969 | } |
| 1970 | |
| 1971 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1972 | friend bool operator==(const T &lhs, Approx const &rhs) { |
| 1973 | auto lhs_v = static_cast<double>(lhs); |
| 1974 | return rhs.equalityComparisonImpl(lhs_v); |
| 1975 | } |
| 1976 | |
| 1977 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1978 | friend bool operator==(Approx const &lhs, const T &rhs) { |
| 1979 | return operator==(rhs, lhs); |
| 1980 | } |
| 1981 | |
| 1982 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1983 | friend bool operator!=(T const &lhs, Approx const &rhs) { |
| 1984 | return !operator==(lhs, rhs); |
| 1985 | } |
| 1986 | |
| 1987 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1988 | friend bool operator!=(Approx const &lhs, T const &rhs) { |
| 1989 | return !operator==(rhs, lhs); |
| 1990 | } |
| 1991 | |
| 1992 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1993 | friend bool operator<=(T const &lhs, Approx const &rhs) { |
| 1994 | return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; |
| 1995 | } |
| 1996 | |
| 1997 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 1998 | friend bool operator<=(Approx const &lhs, T const &rhs) { |
| 1999 | return lhs.m_value < static_cast<double>(rhs) || lhs == rhs; |
| 2000 | } |
| 2001 | |
| 2002 | template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> |
| 2003 | friend bool operator>=(T const &lhs, Approx const &rhs) { |
| 2004 | return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; |
| 2005 | } |
| 2006 | |