FloatOptional GCC build fix and more constexpr (#1411)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1411 X-link: https://github.com/facebook/react-native/pull/39796 Pull Request resolved: https://github.com/facebook/yoga/pull/1414 GCC flags that `isUndefined()` is not declared `constexpr` but that `unwrapOrDefault()` is. `std::isnan` is not constexpr until C++ 23 (because we cannot have nice things), so I made `yoga::isUndefined()` constexpr, using the same code `std::isnan()` boils down to. I then made `FloatOptional` depend on `Comparison.h` (instead of the other way around), so we can use it. Note that the use of the `std::floating_point` concept here requires the libc++ bump in the previous diff in the stack. Reviewed By: yungsters Differential Revision: D49896837 fbshipit-source-id: 61e2bbbfedecffd007a12d42d998e43d3cf5119c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f700e1335c
commit
7fe6e345a7
@@ -5,6 +5,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <yoga/YGValue.h>
|
||||
|
@@ -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<float>(flexLine.itemsInFlow.size() - 1);
|
||||
}
|
||||
break;
|
||||
|
@@ -7,63 +7,49 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include <yoga/Yoga.h>
|
||||
#include <yoga/numeric/FloatOptional.h>
|
||||
|
||||
namespace facebook::yoga {
|
||||
|
||||
template <typename FloatT>
|
||||
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;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <yoga/numeric/Comparison.h>
|
||||
#include <limits>
|
||||
|
||||
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
|
||||
|
Reference in New Issue
Block a user