| /* |
| * 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 |