diff --git a/tests/FloatOptionalTest.cpp b/tests/FloatOptionalTest.cpp index 9163a0a1..2e1f37ce 100644 --- a/tests/FloatOptionalTest.cpp +++ b/tests/FloatOptionalTest.cpp @@ -5,6 +5,8 @@ * LICENSE file in the root directory of this source tree. */ +#include + #include #include diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index f13af3a2..d2d56b7d 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -563,10 +563,10 @@ static void measureNodeWithMeasureFunc( // We want to make sure we don't call measure with negative size const float innerWidth = yoga::isUndefined(availableWidth) ? availableWidth - : yoga::maxOrDefined(0, availableWidth - paddingAndBorderAxisRow); + : yoga::maxOrDefined(0.0f, availableWidth - paddingAndBorderAxisRow); const float innerHeight = yoga::isUndefined(availableHeight) ? availableHeight - : yoga::maxOrDefined(0, availableHeight - paddingAndBorderAxisColumn); + : yoga::maxOrDefined(0.0f, availableHeight - paddingAndBorderAxisColumn); if (widthMeasureMode == MeasureMode::Exactly && heightMeasureMode == MeasureMode::Exactly) { @@ -1223,7 +1223,7 @@ static void justifyMainAxis( const float occupiedSpaceByChildNodes = availableInnerMainDim - flexLine.layout.remainingFreeSpace; flexLine.layout.remainingFreeSpace = yoga::maxOrDefined( - 0, minAvailableMainDim - occupiedSpaceByChildNodes); + 0.0f, minAvailableMainDim - occupiedSpaceByChildNodes); } else { flexLine.layout.remainingFreeSpace = 0; } @@ -1260,7 +1260,7 @@ static void justifyMainAxis( case Justify::SpaceBetween: if (flexLine.itemsInFlow.size() > 1) { betweenMainDim += - yoga::maxOrDefined(flexLine.layout.remainingFreeSpace, 0) / + yoga::maxOrDefined(flexLine.layout.remainingFreeSpace, 0.0f) / static_cast(flexLine.itemsInFlow.size() - 1); } break; diff --git a/yoga/numeric/Comparison.h b/yoga/numeric/Comparison.h index 99eb180d..b881810b 100644 --- a/yoga/numeric/Comparison.h +++ b/yoga/numeric/Comparison.h @@ -7,63 +7,49 @@ #pragma once +#include #include +#include #include -#include namespace facebook::yoga { -template -inline bool isUndefined(FloatT value) { - return std::isnan(value); +constexpr bool isUndefined(auto value) { + return value != value; } -inline float maxOrDefined(const float a, const float b) { +constexpr auto maxOrDefined(auto a, auto b) { if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fmaxf(a, b); + return std::max(a, b); } return yoga::isUndefined(a) ? b : a; } -inline float minOrDefined(const float a, const float b) { +constexpr auto minOrDefined(auto a, auto b) { if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fminf(a, b); + return std::min(a, b); } return yoga::isUndefined(a) ? b : a; } -inline FloatOptional maxOrDefined(FloatOptional op1, FloatOptional op2) { - if (op1 >= op2) { - return op1; - } - if (op2 > op1) { - return op2; - } - return op1.isUndefined() ? op2 : op1; -} - // Custom equality functions using a hardcoded epsilon of 0.0001f, or returning // true if both floats are NaN. -inline bool inexactEquals(const float a, const float b) { +inline bool inexactEquals(float a, float b) { if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fabs(a - b) < 0.0001f; + return std::abs(a - b) < 0.0001f; } return yoga::isUndefined(a) && yoga::isUndefined(b); } -inline bool inexactEquals(const double a, const double b) { +inline bool inexactEquals(double a, double b) { if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fabs(a - b) < 0.0001; + return std::abs(a - b) < 0.0001; } return yoga::isUndefined(a) && yoga::isUndefined(b); } -inline bool inexactEquals(const FloatOptional a, const FloatOptional b) { - return inexactEquals(a.unwrap(), b.unwrap()); -} - inline bool inexactEquals(const YGValue& a, const YGValue& b) { if (a.unit != b.unit) { return false; diff --git a/yoga/numeric/FloatOptional.h b/yoga/numeric/FloatOptional.h index 62e22f36..8fd9bbb2 100644 --- a/yoga/numeric/FloatOptional.h +++ b/yoga/numeric/FloatOptional.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include namespace facebook::yoga { @@ -29,53 +29,61 @@ struct FloatOptional { return isUndefined() ? defaultValue : value_; } - bool isUndefined() const { - return std::isnan(value_); + constexpr bool isUndefined() const { + return yoga::isUndefined(value_); } }; // operators take FloatOptional by value, as it is a 32bit value -inline bool operator==(FloatOptional lhs, FloatOptional rhs) { +constexpr bool operator==(FloatOptional lhs, FloatOptional rhs) { return lhs.unwrap() == rhs.unwrap() || (lhs.isUndefined() && rhs.isUndefined()); } -inline bool operator!=(FloatOptional lhs, FloatOptional rhs) { +constexpr bool operator!=(FloatOptional lhs, FloatOptional rhs) { return !(lhs == rhs); } -inline bool operator==(FloatOptional lhs, float rhs) { +constexpr bool operator==(FloatOptional lhs, float rhs) { return lhs == FloatOptional{rhs}; } -inline bool operator!=(FloatOptional lhs, float rhs) { +constexpr bool operator!=(FloatOptional lhs, float rhs) { return !(lhs == rhs); } -inline bool operator==(float lhs, FloatOptional rhs) { +constexpr bool operator==(float lhs, FloatOptional rhs) { return rhs == lhs; } -inline bool operator!=(float lhs, FloatOptional rhs) { +constexpr bool operator!=(float lhs, FloatOptional rhs) { return !(lhs == rhs); } -inline FloatOptional operator+(FloatOptional lhs, FloatOptional rhs) { +constexpr FloatOptional operator+(FloatOptional lhs, FloatOptional rhs) { return FloatOptional{lhs.unwrap() + rhs.unwrap()}; } -inline bool operator>(FloatOptional lhs, FloatOptional rhs) { +constexpr bool operator>(FloatOptional lhs, FloatOptional rhs) { return lhs.unwrap() > rhs.unwrap(); } -inline bool operator<(FloatOptional lhs, FloatOptional rhs) { +constexpr bool operator<(FloatOptional lhs, FloatOptional rhs) { return lhs.unwrap() < rhs.unwrap(); } -inline bool operator>=(FloatOptional lhs, FloatOptional rhs) { +constexpr bool operator>=(FloatOptional lhs, FloatOptional rhs) { return lhs > rhs || lhs == rhs; } -inline bool operator<=(FloatOptional lhs, FloatOptional rhs) { +constexpr bool operator<=(FloatOptional lhs, FloatOptional rhs) { return lhs < rhs || lhs == rhs; } +constexpr FloatOptional maxOrDefined(FloatOptional lhs, FloatOptional rhs) { + return FloatOptional{yoga::maxOrDefined(lhs.unwrap(), rhs.unwrap())}; +} + +inline bool inexactEquals(FloatOptional lhs, FloatOptional rhs) { + return yoga::inexactEquals(lhs.unwrap(), rhs.unwrap()); +} + } // namespace facebook::yoga