text: /*
   *  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 <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 );
      }
  
      std::string Approx::toString() const {
          std::ostringstream oss;
          oss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
          return oss.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)));
      }
  
  } // end namespace Detail
  
  std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
      return value.toString();
  }
  
  } // end namespace Catch
  