Fix compilation error with CATCH_CONFIG_GLOBAL_NEXTAFTER

Wrong nesting of namespaces resulted in the `Catch` namespace
being ambigous between `::Catch` and `::{anon}::Catch` namespaces.
This should fix it.

Closes #1761
This commit is contained in:
Martin Hořeňovský 2019-10-05 20:58:11 +02:00
parent c38a5caa2e
commit 4bd2c3ad6a
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A

View File

@ -22,55 +22,51 @@
namespace Catch { namespace Catch {
namespace Matchers {
namespace Floating {
enum class FloatingPointKind : uint8_t {
Float,
Double
};
}
}
}
namespace { namespace {
int32_t convert(float f) { int32_t convert(float f) {
static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated"); static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
int32_t i; int32_t i;
std::memcpy(&i, &f, sizeof(f)); std::memcpy(&i, &f, sizeof(f));
return i; return i;
}
int64_t convert(double d) {
static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
int64_t i;
std::memcpy(&i, &d, sizeof(d));
return i;
}
template <typename FP>
bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
// Comparison with NaN should always be false.
// This way we can rule it out before getting into the ugly details
if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
return false;
} }
auto lc = convert(lhs); int64_t convert(double d) {
auto rc = convert(rhs); static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
int64_t i;
if ((lc < 0) != (rc < 0)) { std::memcpy(&i, &d, sizeof(d));
// Potentially we can have +0 and -0 return i;
return lhs == rhs;
} }
auto ulpDiff = std::abs(lc - rc); template <typename FP>
return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff; bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
// Comparison with NaN should always be false.
// This way we can rule it out before getting into the ugly details
if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
return false;
}
auto lc = convert(lhs);
auto rc = convert(rhs);
if ((lc < 0) != (rc < 0)) {
// Potentially we can have +0 and -0
return lhs == rhs;
}
auto ulpDiff = std::abs(lc - rc);
return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
}
} }
#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
namespace Catch { #if defined(__clang__)
#pragma clang diagnostic push
// The long double overload is currently unused
#pragma clang diagnostic ignored "-Wunused-function"
#endif
float nextafter(float x, float y) { float nextafter(float x, float y) {
return ::nextafterf(x, y); return ::nextafterf(x, y);
} }
@ -82,10 +78,15 @@ namespace Catch {
long double nextafter(long double x, long double y) { long double nextafter(long double x, long double y) {
return ::nextafterl(x, y); return ::nextafterl(x, y);
} }
} // end namespace Catch
#if defined(__clang__)
#pragma clang diagnostic pop
#endif #endif
#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
namespace {
template <typename FP> template <typename FP>
FP step(FP start, FP direction, uint64_t steps) { FP step(FP start, FP direction, uint64_t steps) {
for (uint64_t i = 0; i < steps; ++i) { for (uint64_t i = 0; i < steps; ++i) {
@ -97,13 +98,17 @@ FP step(FP start, FP direction, uint64_t steps) {
} }
return start; return start;
} }
} // end anonymous namespace } // end anonymous namespace
namespace Catch {
namespace Matchers { namespace Matchers {
namespace Floating { namespace Floating {
enum class FloatingPointKind : uint8_t {
Float,
Double
};
WithinAbsMatcher::WithinAbsMatcher(double target, double margin) WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
:m_target{ target }, m_margin{ margin } { :m_target{ target }, m_margin{ margin } {
CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.' CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'