Browse Source

approximatelyEqual: Fix unreachable code warning in MSVC

v7.0.9
Anthony Nicholls 1 year ago
parent
commit
2aff537ced
2 changed files with 69 additions and 8 deletions
  1. +9
    -8
      modules/juce_core/maths/juce_MathsFunctions.h
  2. +60
    -0
      modules/juce_core/maths/juce_MathsFunctions_test.cpp

+ 9
- 8
modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -268,10 +268,7 @@ static Tolerance<Type> relativeTolerance (Type tolerance)
} }
/** Returns true if the two numbers are approximately equal. This is useful for floating-point
comparisons.
If a and b are not floating-point types, returns a == b.
/** Returns true if the two floating-point numbers are approximately equal.
If either a or b are not finite, returns exactlyEqual (a, b). If either a or b are not finite, returns exactlyEqual (a, b).
@@ -294,15 +291,12 @@ static Tolerance<Type> relativeTolerance (Type tolerance)
@see exactlyEqual @see exactlyEqual
*/ */
template <typename Type>
template <typename Type, std::enable_if_t<std::is_floating_point_v<Type>, int> = 0>
constexpr bool approximatelyEqual (Type a, Type b, constexpr bool approximatelyEqual (Type a, Type b,
Tolerance<Type> tolerance = Tolerance<Type>{} Tolerance<Type> tolerance = Tolerance<Type>{}
.withAbsolute (std::numeric_limits<Type>::min()) .withAbsolute (std::numeric_limits<Type>::min())
.withRelative (std::numeric_limits<Type>::epsilon())) .withRelative (std::numeric_limits<Type>::epsilon()))
{ {
if constexpr (! std::is_floating_point_v<Type>)
return a == b;
if (! (juce_isfinite (a) && juce_isfinite (b))) if (! (juce_isfinite (a) && juce_isfinite (b)))
return exactlyEqual (a, b); return exactlyEqual (a, b);
@@ -312,6 +306,13 @@ constexpr bool approximatelyEqual (Type a, Type b,
|| diff <= tolerance.getRelative() * std::max (std::abs (a), std::abs (b)); || diff <= tolerance.getRelative() * std::max (std::abs (a), std::abs (b));
} }
/** Special case for non-floating-point types that returns true if both are exactly equal. */
template <typename Type, std::enable_if_t<! std::is_floating_point_v<Type>, int> = 0>
constexpr bool approximatelyEqual (Type a, Type b)
{
return a == b;
}
//============================================================================== //==============================================================================
/** Returns the next representable value by FloatType in the direction of the largest representable value. */ /** Returns the next representable value by FloatType in the direction of the largest representable value. */
template <typename FloatType> template <typename FloatType>


+ 60
- 0
modules/juce_core/maths/juce_MathsFunctions_test.cpp View File

@@ -29,6 +29,9 @@ String getTemplatedMathsFunctionUnitTestName (const String& functionName)
{ {
const auto getTypeName = []() -> String const auto getTypeName = []() -> String
{ {
if constexpr (std::is_same_v<int, T>)
return "int";
if constexpr (std::is_same_v<float, T>) if constexpr (std::is_same_v<float, T>)
return "float"; return "float";
@@ -358,6 +361,56 @@ public:
} }
}; };
template<>
class ApproximatelyEqualTests<int> final : public UnitTest
{
public:
ApproximatelyEqualTests()
: UnitTest { getTemplatedMathsFunctionUnitTestName<int> ("approximatelyEqual"), UnitTestCategories::maths }
{}
void runTest() final
{
beginTest ("Identical integers are always equal");
{
expect (approximatelyEqual ( 0, 0));
expect (approximatelyEqual (-0, -0));
expect (approximatelyEqual ( 1, 1));
expect (approximatelyEqual (-1, -1));
using limits = std::numeric_limits<int>;
constexpr auto min = limits::min();
constexpr auto max = limits::max();
expect (approximatelyEqual (min, min));
expect (approximatelyEqual (max, max));
}
beginTest ("Non-identical integers are never equal");
{
expect (! approximatelyEqual ( 0, 1));
expect (! approximatelyEqual ( 0, -1));
expect (! approximatelyEqual ( 1, 2));
expect (! approximatelyEqual (-1, -2));
using limits = std::numeric_limits<int>;
constexpr auto min = limits::min();
constexpr auto max = limits::max();
expect (! approximatelyEqual (min, min + 1));
expect (! approximatelyEqual (max, max - 1));
}
beginTest ("Zero is equal regardless of the sign");
{
expect (approximatelyEqual ( 0, -0));
expect (approximatelyEqual (-0, 0));
}
}
};
template <typename T> template <typename T>
class IsFiniteTests final : public UnitTest class IsFiniteTests final : public UnitTest
{ {
@@ -471,8 +524,15 @@ struct MathsFloatingPointFunctionsTests
ApproximatelyEqualTests<Type> approximatelyEqualTests; ApproximatelyEqualTests<Type> approximatelyEqualTests;
}; };
template<>
struct MathsFloatingPointFunctionsTests<int>
{
ApproximatelyEqualTests<int> approximatelyEqualTests;
};
struct MathsFunctionsTests struct MathsFunctionsTests
{ {
MathsFloatingPointFunctionsTests<int> intFunctionTests;
MathsFloatingPointFunctionsTests<float> floatFunctionTests; MathsFloatingPointFunctionsTests<float> floatFunctionTests;
MathsFloatingPointFunctionsTests<double> doubleFunctionTests; MathsFloatingPointFunctionsTests<double> doubleFunctionTests;
MathsFloatingPointFunctionsTests<long double> longDoubleFunctionTests; MathsFloatingPointFunctionsTests<long double> longDoubleFunctionTests;


Loading…
Cancel
Save