mirror of https://github.com/procxx/kepka.git
				
				
				
			
		
			
				
	
	
		
			134 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  *  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>
 | |
| #include <stdexcept>
 | |
| 
 | |
| namespace Catch {
 | |
| namespace Detail {
 | |
| 
 | |
|     class Approx {
 | |
|     private:
 | |
|         bool equalityComparisonImpl(double other) const;
 | |
| 
 | |
|     public:
 | |
|         explicit Approx ( double value );
 | |
| 
 | |
|         static Approx custom();
 | |
| 
 | |
|         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.epsilon( m_epsilon );
 | |
|             approx.margin( m_margin );
 | |
|             approx.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);
 | |
|             if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
 | |
|                 throw std::domain_error
 | |
|                     (   "Invalid Approx::epsilon: " +
 | |
|                         Catch::Detail::stringify( epsilonAsDouble ) +
 | |
|                         ", Approx::epsilon has to be between 0 and 1" );
 | |
|             }
 | |
|             m_epsilon = 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);
 | |
|             if( marginAsDouble < 0 ) {
 | |
|                 throw std::domain_error
 | |
|                     (   "Invalid Approx::margin: " +
 | |
|                          Catch::Detail::stringify( marginAsDouble ) +
 | |
|                          ", Approx::Margin has to be non-negative." );
 | |
| 
 | |
|             }
 | |
|             m_margin = 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;
 | |
|     };
 | |
| }
 | |
| 
 | |
| template<>
 | |
| struct StringMaker<Catch::Detail::Approx> {
 | |
|     static std::string convert(Catch::Detail::Approx const& value);
 | |
| };
 | |
| 
 | |
| } // end namespace Catch
 | |
| 
 | |
| #endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
 |