2017-11-10 18:14:42 +01:00
|
|
|
/*
|
|
|
|
* 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> {
|
2019-10-05 13:23:14 +02:00
|
|
|
WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
|
2017-11-10 18:14:42 +01:00
|
|
|
bool match(double const& matchee) const override;
|
|
|
|
std::string describe() const override;
|
|
|
|
private:
|
|
|
|
double m_target;
|
2019-10-05 13:23:14 +02:00
|
|
|
uint64_t m_ulps;
|
2017-11-10 18:14:42 +01:00
|
|
|
FloatingPointKind m_type;
|
|
|
|
};
|
|
|
|
|
2019-10-13 11:56:50 +02:00
|
|
|
// 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;
|
|
|
|
};
|
2017-11-10 18:14:42 +01:00
|
|
|
|
|
|
|
} // namespace Floating
|
|
|
|
|
2017-11-10 18:37:58 +01:00
|
|
|
// The following functions create the actual matcher objects.
|
|
|
|
// This allows the types to be inferred
|
2019-10-05 13:23:14 +02:00
|
|
|
Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
|
|
|
|
Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
|
2017-11-10 18:14:42 +01:00
|
|
|
Floating::WithinAbsMatcher WithinAbs(double target, double margin);
|
2019-10-13 11:56:50 +02:00
|
|
|
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);
|
2017-11-10 18:14:42 +01:00
|
|
|
|
|
|
|
} // namespace Matchers
|
|
|
|
} // namespace Catch
|
|
|
|
|
|
|
|
#endif // TWOBLUECUBES_CATCH_MATCHERS_FLOATING_H_INCLUDED
|