|  | /* | 
|  | *  Created by Martin on 07/11/2017. | 
|  | * | 
|  | * 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_MATCHERS_FLOATING_H_INCLUDED | 
|  | #define TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED | 
|  |  | 
|  | #include "catch_matchers.h" | 
|  |  | 
|  | namespace Catch { | 
|  | namespace Matchers { | 
|  |  | 
|  | namespace Floating { | 
|  |  | 
|  | enum class FloatingPointKind : uint8_t; | 
|  |  | 
|  | struct WithinAbsMatcher : MatcherBase<double> { | 
|  | WithinAbsMatcher(double target, double margin); | 
|  | bool match(double const& matchee) const override; | 
|  | std::string describe() const override; | 
|  | private: | 
|  | double m_target; | 
|  | double m_margin; | 
|  | }; | 
|  |  | 
|  | struct WithinUlpsMatcher : MatcherBase<double> { | 
|  | WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType); | 
|  | bool match(double const& matchee) const override; | 
|  | std::string describe() const override; | 
|  | private: | 
|  | double m_target; | 
|  | uint64_t m_ulps; | 
|  | FloatingPointKind m_type; | 
|  | }; | 
|  |  | 
|  | // Given IEEE-754 format for floats and doubles, we can assume | 
|  | // that float -> double promotion is lossless. Given this, we can | 
|  | // assume that if we do the standard relative comparison of | 
|  | // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get | 
|  | // the same result if we do this for floats, as if we do this for | 
|  | // doubles that were promoted from floats. | 
|  | struct WithinRelMatcher : MatcherBase<double> { | 
|  | WithinRelMatcher(double target, double epsilon); | 
|  | bool match(double const& matchee) const override; | 
|  | std::string describe() const override; | 
|  | private: | 
|  | double m_target; | 
|  | double m_epsilon; | 
|  | }; | 
|  |  | 
|  | } // namespace Floating | 
|  |  | 
|  | // The following functions create the actual matcher objects. | 
|  | // This allows the types to be inferred | 
|  | Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff); | 
|  | Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff); | 
|  | Floating::WithinAbsMatcher WithinAbs(double target, double margin); | 
|  | Floating::WithinRelMatcher WithinRel(double target, double eps); | 
|  | // defaults epsilon to 100*numeric_limits<double>::epsilon() | 
|  | Floating::WithinRelMatcher WithinRel(double target); | 
|  | Floating::WithinRelMatcher WithinRel(float target, float eps); | 
|  | // defaults epsilon to 100*numeric_limits<float>::epsilon() | 
|  | Floating::WithinRelMatcher WithinRel(float target); | 
|  |  | 
|  | } // namespace Matchers | 
|  | } // namespace Catch | 
|  |  | 
|  | #endif // TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED |