| 
									
										
										
										
											2011-04-28 08:03:28 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 06:51:58 +01:00
										 |  |  | #include "catch_tostring.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-28 08:03:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <cmath>
 | 
					
						
							| 
									
										
										
										
											2011-04-28 08:20:47 +01:00
										 |  |  | #include <limits>
 | 
					
						
							| 
									
										
										
										
											2011-04-28 08:03:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  | namespace Catch { | 
					
						
							|  |  |  | namespace Detail { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class Approx { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         explicit Approx ( double value ) | 
					
						
							|  |  |  |         :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ), | 
					
						
							|  |  |  |             m_scale( 1.0 ), | 
					
						
							|  |  |  |             m_value( value ) | 
					
						
							|  |  |  |         {} | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |         Approx( Approx const& other ) | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |         :   m_epsilon( other.m_epsilon ), | 
					
						
							|  |  |  |             m_scale( other.m_scale ), | 
					
						
							|  |  |  |             m_value( other.m_value ) | 
					
						
							|  |  |  |         {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static Approx custom() { | 
					
						
							|  |  |  |             return Approx( 0 ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |         Approx operator()( double value ) { | 
					
						
							|  |  |  |             Approx approx( value ); | 
					
						
							|  |  |  |             approx.epsilon( m_epsilon ); | 
					
						
							|  |  |  |             approx.scale( m_scale ); | 
					
						
							|  |  |  |             return approx; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |         friend bool operator == ( double lhs, Approx const& rhs ) { | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |             // Thanks to Richard Harris for his help refining this formula
 | 
					
						
							|  |  |  |             return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |         friend bool operator == ( Approx const& lhs, double rhs ) { | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |             return operator==( rhs, lhs ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |         friend bool operator != ( double lhs, Approx const& rhs ) { | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |             return !operator==( lhs, rhs ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-06-06 08:21:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |         friend bool operator != ( Approx const& lhs, double rhs ) { | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |             return !operator==( rhs, lhs ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |         Approx& epsilon( double newEpsilon ) { | 
					
						
							|  |  |  |             m_epsilon = newEpsilon; | 
					
						
							|  |  |  |             return *this; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |         Approx& scale( double newScale ) { | 
					
						
							|  |  |  |             m_scale = newScale; | 
					
						
							|  |  |  |             return *this; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |         std::string toString() const { | 
					
						
							|  |  |  |             std::ostringstream oss; | 
					
						
							| 
									
										
										
										
											2013-12-19 18:41:55 +00:00
										 |  |  |             oss << "Approx( " << Catch::toString( m_value ) << " )"; | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |             return oss.str(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     private: | 
					
						
							|  |  |  |         double m_epsilon; | 
					
						
							|  |  |  |         double m_scale; | 
					
						
							|  |  |  |         double m_value; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-04-28 08:20:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  | template<> | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  | inline std::string toString<Detail::Approx>( Detail::Approx const& value ) { | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     return value.toString(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-28 08:03:28 +01:00
										 |  |  | } // end namespace Catch
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
 |