mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 00:51:52 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			88 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 *  Created by Martin on 19/07/2017.
 | 
						|
 *  Copyright 2017 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)
 | 
						|
 */
 | 
						|
 | 
						|
#include "catch_approx.h"
 | 
						|
#include "catch_enforce.h"
 | 
						|
 | 
						|
#include <cmath>
 | 
						|
#include <limits>
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
// Performs equivalent check of std::fabs(lhs - rhs) <= margin
 | 
						|
// But without the subtraction to allow for INFINITY in comparison
 | 
						|
bool marginComparison(double lhs, double rhs, double margin) {
 | 
						|
    return (lhs + margin >= rhs) && (rhs + margin >= lhs);
 | 
						|
}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
namespace Catch {
 | 
						|
namespace Detail {
 | 
						|
 | 
						|
    Approx::Approx ( double value )
 | 
						|
    :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
 | 
						|
        m_margin( 0.0 ),
 | 
						|
        m_scale( 0.0 ),
 | 
						|
        m_value( value )
 | 
						|
    {}
 | 
						|
 | 
						|
    Approx Approx::custom() {
 | 
						|
        return Approx( 0 );
 | 
						|
    }
 | 
						|
 | 
						|
    Approx Approx::operator-() const {
 | 
						|
        auto temp(*this);
 | 
						|
        temp.m_value = -temp.m_value;
 | 
						|
        return temp;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    std::string Approx::toString() const {
 | 
						|
        ReusableStringStream rss;
 | 
						|
        rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
 | 
						|
        return rss.str();
 | 
						|
    }
 | 
						|
 | 
						|
    bool Approx::equalityComparisonImpl(const double other) const {
 | 
						|
        // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
 | 
						|
        // Thanks to Richard Harris for his help refining the scaled margin value
 | 
						|
        return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
 | 
						|
    }
 | 
						|
 | 
						|
    void Approx::setMargin(double margin) {
 | 
						|
        CATCH_ENFORCE(margin >= 0,
 | 
						|
            "Invalid Approx::margin: " << margin << '.'
 | 
						|
            << " Approx::Margin has to be non-negative.");
 | 
						|
        m_margin = margin;
 | 
						|
    }
 | 
						|
 | 
						|
    void Approx::setEpsilon(double epsilon) {
 | 
						|
        CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
 | 
						|
            "Invalid Approx::epsilon: " << epsilon << '.'
 | 
						|
            << " Approx::epsilon has to be in [0, 1]");
 | 
						|
        m_epsilon = epsilon;
 | 
						|
    }
 | 
						|
 | 
						|
} // end namespace Detail
 | 
						|
 | 
						|
namespace literals {
 | 
						|
    Detail::Approx operator "" _a(long double val) {
 | 
						|
        return Detail::Approx(val);
 | 
						|
    }
 | 
						|
    Detail::Approx operator "" _a(unsigned long long val) {
 | 
						|
        return Detail::Approx(val);
 | 
						|
    }
 | 
						|
} // end namespace literals
 | 
						|
 | 
						|
std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
 | 
						|
    return value.toString();
 | 
						|
}
 | 
						|
 | 
						|
} // end namespace Catch
 |