| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 | /* *  Created by Phil on 28/04/2011. *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * *  Distributed under the Boost Software License, Version 1.0. (See accompanying *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */#ifndef TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED#include "catch_tostring.h"#include <type_traits>namespace Catch {namespace Detail {    class Approx {    private:        bool equalityComparisonImpl(double other) const;        // Validates the new margin (margin >= 0)        // out-of-line to avoid including stdexcept in the header        void setMargin(double margin);        // Validates the new epsilon (0 < epsilon < 1)        // out-of-line to avoid including stdexcept in the header        void setEpsilon(double epsilon);    public:        explicit Approx ( double value );        static Approx custom();        Approx operator-() const;        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        Approx operator()( T const& value ) {            Approx approx( static_cast<double>(value) );            approx.m_epsilon = m_epsilon;            approx.m_margin = m_margin;            approx.m_scale = m_scale;            return approx;        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        explicit Approx( T const& value ): Approx(static_cast<double>(value))        {}        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator == ( const T& lhs, Approx const& rhs ) {            auto lhs_v = static_cast<double>(lhs);            return rhs.equalityComparisonImpl(lhs_v);        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator == ( Approx const& lhs, const T& rhs ) {            return operator==( rhs, lhs );        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator != ( T const& lhs, Approx const& rhs ) {            return !operator==( lhs, rhs );        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator != ( Approx const& lhs, T const& rhs ) {            return !operator==( rhs, lhs );        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator <= ( T const& lhs, Approx const& rhs ) {            return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator <= ( Approx const& lhs, T const& rhs ) {            return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator >= ( T const& lhs, Approx const& rhs ) {            return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        friend bool operator >= ( Approx const& lhs, T const& rhs ) {            return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        Approx& epsilon( T const& newEpsilon ) {            double epsilonAsDouble = static_cast<double>(newEpsilon);            setEpsilon(epsilonAsDouble);            return *this;        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        Approx& margin( T const& newMargin ) {            double marginAsDouble = static_cast<double>(newMargin);            setMargin(marginAsDouble);            return *this;        }        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>        Approx& scale( T const& newScale ) {            m_scale = static_cast<double>(newScale);            return *this;        }        std::string toString() const;    private:        double m_epsilon;        double m_margin;        double m_scale;        double m_value;    };} // end namespace Detailnamespace literals {    Detail::Approx operator "" _a(long double val);    Detail::Approx operator "" _a(unsigned long long val);} // end namespace literalstemplate<>struct StringMaker<Catch::Detail::Approx> {    static std::string convert(Catch::Detail::Approx const& value);};} // end namespace Catch#endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
 |