Cleanup for floating point matchers

Removed the `Floating` nested namespace and added Doxygen comments
for the factory methods.
This commit is contained in:
Martin Hořeňovský 2020-03-28 12:48:19 +01:00
parent a6baa6dda6
commit afc8b28c07
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
2 changed files with 71 additions and 71 deletions

View File

@ -99,13 +99,15 @@ void write(std::ostream& out, FloatingPoint num) {
} // end anonymous namespace
namespace Matchers {
namespace Floating {
namespace Detail {
enum class FloatingPointKind : uint8_t {
Float,
Double
};
} // end namespace Detail
WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
:m_target{ target }, m_margin{ margin } {
@ -124,9 +126,9 @@ namespace Floating {
}
WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, Detail::FloatingPointKind baseType)
:m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
CATCH_ENFORCE(m_type == FloatingPointKind::Double
CATCH_ENFORCE(m_type == Detail::FloatingPointKind::Double
|| m_ulps < (std::numeric_limits<uint32_t>::max)(),
"Provided ULP is impossibly large for a float comparison.");
}
@ -139,12 +141,12 @@ namespace Floating {
bool WithinUlpsMatcher::match(double const& matchee) const {
switch (m_type) {
case FloatingPointKind::Float:
case Detail::FloatingPointKind::Float:
return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
case FloatingPointKind::Double:
case Detail::FloatingPointKind::Double:
return almostEqualUlps<double>(matchee, m_target, m_ulps);
default:
CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
CATCH_INTERNAL_ERROR( "Unknown Detail::FloatingPointKind value" );
}
}
@ -157,7 +159,7 @@ namespace Floating {
ret << "is within " << m_ulps << " ULPs of ";
if (m_type == FloatingPointKind::Float) {
if (m_type == Detail::FloatingPointKind::Float) {
write(ret, static_cast<float>(m_target));
ret << 'f';
} else {
@ -165,7 +167,7 @@ namespace Floating {
}
ret << " ([";
if (m_type == FloatingPointKind::Double) {
if (m_type == Detail::FloatingPointKind::Double) {
write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
ret << ", ";
write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
@ -199,39 +201,35 @@ namespace Floating {
return sstr.str();
}
}// namespace Floating
Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
return WithinUlpsMatcher(target, maxUlpDiff, Detail::FloatingPointKind::Double);
}
Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
return WithinUlpsMatcher(target, maxUlpDiff, Detail::FloatingPointKind::Float);
}
Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
return Floating::WithinAbsMatcher(target, margin);
WithinAbsMatcher WithinAbs(double target, double margin) {
return WithinAbsMatcher(target, margin);
}
Floating::WithinRelMatcher WithinRel(double target, double eps) {
return Floating::WithinRelMatcher(target, eps);
WithinRelMatcher WithinRel(double target, double eps) {
return WithinRelMatcher(target, eps);
}
Floating::WithinRelMatcher WithinRel(double target) {
return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
WithinRelMatcher WithinRel(double target) {
return WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
}
Floating::WithinRelMatcher WithinRel(float target, float eps) {
return Floating::WithinRelMatcher(target, eps);
WithinRelMatcher WithinRel(float target, float eps) {
return WithinRelMatcher(target, eps);
}
Floating::WithinRelMatcher WithinRel(float target) {
return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
WithinRelMatcher WithinRel(float target) {
return WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
}
} // namespace Matchers
} // namespace Catch

View File

@ -12,57 +12,59 @@
namespace Catch {
namespace Matchers {
namespace Floating {
namespace Detail {
enum class FloatingPointKind : uint8_t;
}
struct WithinAbsMatcher final : 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 WithinAbsMatcher final : 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 final : 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;
};
struct WithinUlpsMatcher final : MatcherBase<double> {
WithinUlpsMatcher(double target, uint64_t ulps, Detail::FloatingPointKind baseType);
bool match(double const& matchee) const override;
std::string describe() const override;
private:
double m_target;
uint64_t m_ulps;
Detail::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 final : 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;
};
// 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 final : 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
//! Creates a matcher that accepts doubles within certain ULP range of target
WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
//! Creates a matcher that accepts floats within certain ULP range of target
WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
//! Creates a matcher that accepts numbers within certain range of target
WithinAbsMatcher WithinAbs(double target, double margin);
// 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);
//! Creates a matcher that accepts doubles within certain relative range of target
WithinRelMatcher WithinRel(double target, double eps);
//! Creates a matcher that accepts doubles within 100*DBL_EPS relative range of target
WithinRelMatcher WithinRel(double target);
//! Creates a matcher that accepts doubles within certain relative range of target
WithinRelMatcher WithinRel(float target, float eps);
//! Creates a matcher that accepts floats within 100*FLT_EPS relative range of target
WithinRelMatcher WithinRel(float target);
} // namespace Matchers
} // namespace Catch