Back out Stack D13119110..D13236159
Summary: backout, causes failures Reviewed By: adityasharat Differential Revision: D13376210 fbshipit-source-id: 1fa8823f2dce601c47738f34ddb2674288197e79
This commit is contained in:
committed by
Facebook Github Bot
parent
6b7f6980f9
commit
b26e637c81
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the MIT license found in the
|
* This source code is licensed under the MIT license found in the
|
||||||
@@ -9,11 +9,28 @@ namespace Facebook.Yoga
|
|||||||
{
|
{
|
||||||
public static class YogaConstants
|
public static class YogaConstants
|
||||||
{
|
{
|
||||||
public const float Undefined = float.NaN;
|
/**
|
||||||
|
* Large positive number signifies that the property(float) is undefined. Earlier we used to have
|
||||||
|
* YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as
|
||||||
|
* it assumes all floating-point calculation involve and result into finite numbers. For more
|
||||||
|
* information regarding -ffast-math compiler flag in clang, have a look at
|
||||||
|
* https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math
|
||||||
|
*/
|
||||||
|
public const float Undefined = 10E20F;
|
||||||
|
|
||||||
public static bool IsUndefined(float value)
|
public static bool IsUndefined(float value)
|
||||||
{
|
{
|
||||||
return float.IsNaN(value);
|
// Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN,
|
||||||
|
// the benefit of which
|
||||||
|
// was that if NAN is involved in any mathematical expression the result was NAN. But since we
|
||||||
|
// want to have `-ffast-math`
|
||||||
|
// flag being used by compiler which assumes that the floating point values are not NAN and Inf,
|
||||||
|
// we represent YGUndefined as 10.1E20.
|
||||||
|
// But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would
|
||||||
|
// change.
|
||||||
|
// So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it
|
||||||
|
// is undefined.
|
||||||
|
return value >= 10E8F || value <= -10E8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsUndefined(YogaValue value)
|
public static bool IsUndefined(YogaValue value)
|
||||||
|
@@ -1,17 +1,35 @@
|
|||||||
/**
|
/*
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
|
* file in the root directory of this source tree.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the MIT license found in the LICENSE
|
|
||||||
* file in the root directory of this source tree.
|
|
||||||
*/
|
*/
|
||||||
package com.facebook.yoga;
|
package com.facebook.yoga;
|
||||||
|
|
||||||
public class YogaConstants {
|
public class YogaConstants {
|
||||||
|
|
||||||
public static final float UNDEFINED = Float.NaN;
|
/**
|
||||||
|
* Large positive number signifies that the property(float) is undefined. Earlier we used to have
|
||||||
|
* YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as
|
||||||
|
* it assumes all floating-point calculation involve and result into finite numbers. For more
|
||||||
|
* information regarding -ffast-math compiler flag in clang, have a look at
|
||||||
|
* https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math
|
||||||
|
*/
|
||||||
|
public static final float UNDEFINED = (float) (10E20);
|
||||||
|
|
||||||
public static boolean isUndefined(float value) {
|
public static boolean isUndefined(float value) {
|
||||||
return Float.compare(value, UNDEFINED) == 0;
|
// Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN,
|
||||||
|
// the benefit of which
|
||||||
|
// was that if NAN is involved in any mathematical expression the result was NAN. But since we
|
||||||
|
// want to have `-ffast-math`
|
||||||
|
// flag being used by compiler which assumes that the floating point values are not NAN and Inf,
|
||||||
|
// we represent YGUndefined as 10.1E20.
|
||||||
|
// But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would
|
||||||
|
// change.
|
||||||
|
// So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it
|
||||||
|
// is undefined.
|
||||||
|
return (Float.compare(value, (float) 10E8) >= 0 || Float.compare(value, (float) -10E8) <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isUndefined(YogaValue value) {
|
public static boolean isUndefined(YogaValue value) {
|
||||||
|
@@ -1,205 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the LICENSE
|
|
||||||
* file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
#include <yoga/YGFloatOptional.h>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <yoga/YGFloatOptional.h>
|
|
||||||
#include <yoga/Yoga.h>
|
|
||||||
|
|
||||||
constexpr auto empty = YGFloatOptional{};
|
|
||||||
constexpr auto zero = YGFloatOptional{0.0f};
|
|
||||||
constexpr auto one = YGFloatOptional{1.0f};
|
|
||||||
constexpr auto positive = YGFloatOptional{1234.5f};
|
|
||||||
constexpr auto negative = YGFloatOptional{-9876.5f};
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, value) {
|
|
||||||
ASSERT_EQ(zero.unwrap(), 0.0f);
|
|
||||||
ASSERT_EQ(positive.unwrap(), 1234.5f);
|
|
||||||
ASSERT_EQ(negative.unwrap(), -9876.5f);
|
|
||||||
ASSERT_TRUE(YGFloatIsUndefined(empty.unwrap()));
|
|
||||||
|
|
||||||
ASSERT_TRUE(empty.isUndefined());
|
|
||||||
ASSERT_FALSE(zero.isUndefined());
|
|
||||||
ASSERT_FALSE(negative.isUndefined());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, equality) {
|
|
||||||
ASSERT_TRUE(empty == empty);
|
|
||||||
ASSERT_TRUE(empty == YGUndefined);
|
|
||||||
ASSERT_FALSE(empty == zero);
|
|
||||||
ASSERT_FALSE(empty == negative);
|
|
||||||
ASSERT_FALSE(empty == 12.3f);
|
|
||||||
|
|
||||||
ASSERT_TRUE(zero == zero);
|
|
||||||
ASSERT_TRUE(zero == 0.0f);
|
|
||||||
ASSERT_FALSE(zero == positive);
|
|
||||||
ASSERT_FALSE(zero == -5555.5f);
|
|
||||||
|
|
||||||
ASSERT_TRUE(one == one);
|
|
||||||
ASSERT_TRUE(one == 1.0f);
|
|
||||||
ASSERT_FALSE(one == positive);
|
|
||||||
|
|
||||||
ASSERT_TRUE(negative == negative);
|
|
||||||
ASSERT_TRUE(negative == negative.unwrap());
|
|
||||||
ASSERT_FALSE(negative == zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, inequality) {
|
|
||||||
ASSERT_FALSE(empty != empty);
|
|
||||||
ASSERT_FALSE(empty != YGUndefined);
|
|
||||||
ASSERT_TRUE(empty != zero);
|
|
||||||
ASSERT_TRUE(empty != negative);
|
|
||||||
ASSERT_TRUE(empty != 12.3f);
|
|
||||||
|
|
||||||
ASSERT_FALSE(zero != zero);
|
|
||||||
ASSERT_FALSE(zero != 0.0f);
|
|
||||||
ASSERT_TRUE(zero != positive);
|
|
||||||
ASSERT_TRUE(zero != -5555.5f);
|
|
||||||
|
|
||||||
ASSERT_FALSE(one != one);
|
|
||||||
ASSERT_FALSE(one != 1.0f);
|
|
||||||
ASSERT_TRUE(one != positive);
|
|
||||||
|
|
||||||
ASSERT_FALSE(negative != negative);
|
|
||||||
ASSERT_FALSE(negative != negative.unwrap());
|
|
||||||
ASSERT_TRUE(negative != zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, greater) {
|
|
||||||
ASSERT_FALSE(empty > empty);
|
|
||||||
ASSERT_FALSE(empty > zero);
|
|
||||||
ASSERT_FALSE(empty > one);
|
|
||||||
ASSERT_FALSE(empty > positive);
|
|
||||||
ASSERT_FALSE(empty > negative);
|
|
||||||
ASSERT_FALSE(zero > empty);
|
|
||||||
ASSERT_FALSE(one > empty);
|
|
||||||
ASSERT_FALSE(positive > empty);
|
|
||||||
ASSERT_FALSE(negative > empty);
|
|
||||||
|
|
||||||
ASSERT_TRUE(zero > negative);
|
|
||||||
ASSERT_FALSE(zero > zero);
|
|
||||||
ASSERT_FALSE(zero > positive);
|
|
||||||
ASSERT_FALSE(zero > one);
|
|
||||||
|
|
||||||
ASSERT_TRUE(one > negative);
|
|
||||||
ASSERT_TRUE(one > zero);
|
|
||||||
ASSERT_FALSE(one > empty);
|
|
||||||
ASSERT_FALSE(one > positive);
|
|
||||||
|
|
||||||
ASSERT_TRUE(negative > YGFloatOptional{-INFINITY});
|
|
||||||
ASSERT_FALSE(negative > empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, lower) {
|
|
||||||
ASSERT_FALSE(empty < empty);
|
|
||||||
ASSERT_FALSE(empty < zero);
|
|
||||||
ASSERT_FALSE(empty < one);
|
|
||||||
ASSERT_FALSE(empty < positive);
|
|
||||||
ASSERT_FALSE(empty < negative);
|
|
||||||
ASSERT_FALSE(zero < empty);
|
|
||||||
ASSERT_FALSE(one < empty);
|
|
||||||
ASSERT_FALSE(positive < empty);
|
|
||||||
ASSERT_FALSE(negative < empty);
|
|
||||||
|
|
||||||
ASSERT_TRUE(negative < zero);
|
|
||||||
ASSERT_FALSE(zero < zero);
|
|
||||||
ASSERT_FALSE(positive < zero);
|
|
||||||
ASSERT_FALSE(one < zero);
|
|
||||||
|
|
||||||
ASSERT_TRUE(negative < one);
|
|
||||||
ASSERT_TRUE(zero < one);
|
|
||||||
ASSERT_FALSE(empty < one);
|
|
||||||
ASSERT_FALSE(positive < one);
|
|
||||||
|
|
||||||
ASSERT_TRUE(YGFloatOptional{-INFINITY} < negative);
|
|
||||||
ASSERT_FALSE(empty < negative);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, greater_equals) {
|
|
||||||
ASSERT_TRUE(empty >= empty);
|
|
||||||
ASSERT_FALSE(empty >= zero);
|
|
||||||
ASSERT_FALSE(empty >= one);
|
|
||||||
ASSERT_FALSE(empty >= positive);
|
|
||||||
ASSERT_FALSE(empty >= negative);
|
|
||||||
|
|
||||||
ASSERT_TRUE(zero >= negative);
|
|
||||||
ASSERT_TRUE(zero >= zero);
|
|
||||||
ASSERT_FALSE(zero >= positive);
|
|
||||||
ASSERT_FALSE(zero >= one);
|
|
||||||
|
|
||||||
ASSERT_TRUE(one >= negative);
|
|
||||||
ASSERT_TRUE(one >= zero);
|
|
||||||
ASSERT_FALSE(one >= empty);
|
|
||||||
ASSERT_FALSE(one >= positive);
|
|
||||||
|
|
||||||
ASSERT_TRUE(negative >= YGFloatOptional{-INFINITY});
|
|
||||||
ASSERT_TRUE(negative >= negative);
|
|
||||||
ASSERT_FALSE(negative >= empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, lower_equals) {
|
|
||||||
ASSERT_TRUE(empty <= empty);
|
|
||||||
ASSERT_FALSE(zero <= empty);
|
|
||||||
ASSERT_FALSE(one <= empty);
|
|
||||||
ASSERT_FALSE(positive <= empty);
|
|
||||||
ASSERT_FALSE(negative <= empty);
|
|
||||||
|
|
||||||
ASSERT_TRUE(negative <= zero);
|
|
||||||
ASSERT_TRUE(zero <= zero);
|
|
||||||
ASSERT_FALSE(positive <= zero);
|
|
||||||
ASSERT_FALSE(one <= zero);
|
|
||||||
|
|
||||||
ASSERT_TRUE(negative <= one);
|
|
||||||
ASSERT_TRUE(zero <= one);
|
|
||||||
ASSERT_FALSE(empty <= one);
|
|
||||||
ASSERT_FALSE(positive <= one);
|
|
||||||
|
|
||||||
ASSERT_TRUE(YGFloatOptional{-INFINITY} <= negative);
|
|
||||||
ASSERT_TRUE(negative <= negative);
|
|
||||||
ASSERT_FALSE(empty <= negative);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, addition) {
|
|
||||||
ASSERT_EQ(zero + one, one);
|
|
||||||
ASSERT_EQ(
|
|
||||||
negative + positive,
|
|
||||||
YGFloatOptional{negative.unwrap() + positive.unwrap()});
|
|
||||||
ASSERT_EQ(empty + zero, empty);
|
|
||||||
ASSERT_EQ(empty + empty, empty);
|
|
||||||
ASSERT_EQ(negative + empty, empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, subtraction) {
|
|
||||||
ASSERT_EQ(zero - one, YGFloatOptional{-1.0f});
|
|
||||||
ASSERT_EQ(
|
|
||||||
negative - positive,
|
|
||||||
YGFloatOptional{negative.unwrap() - positive.unwrap()});
|
|
||||||
ASSERT_EQ(empty - zero, empty);
|
|
||||||
ASSERT_EQ(empty - empty, empty);
|
|
||||||
ASSERT_EQ(negative - empty, empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, unary_minus) {
|
|
||||||
ASSERT_EQ(-zero, zero);
|
|
||||||
ASSERT_EQ(-negative, YGFloatOptional{-negative.unwrap()});
|
|
||||||
ASSERT_EQ(-positive, YGFloatOptional{-positive.unwrap()});
|
|
||||||
ASSERT_EQ(-empty, empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, orElse) {
|
|
||||||
ASSERT_EQ(empty.orElse(1.23f), 1.23f);
|
|
||||||
ASSERT_TRUE(YGFloatIsUndefined(empty.orElse(YGUndefined)));
|
|
||||||
ASSERT_EQ(one.orElse(1.23f), 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(YGFloatOptional, orElseGet) {
|
|
||||||
auto x = empty.orElseGet([] { return 1.23f; });
|
|
||||||
ASSERT_EQ(x, 1.23f);
|
|
||||||
ASSERT_TRUE(YGFloatIsUndefined(empty.orElseGet([] { return YGUndefined; })));
|
|
||||||
|
|
||||||
auto y = one.orElseGet([] { return 1.23f; });
|
|
||||||
ASSERT_EQ(y, 1.0f);
|
|
||||||
}
|
|
@@ -58,6 +58,7 @@ BASE_COMPILER_FLAGS = [
|
|||||||
"-Wall",
|
"-Wall",
|
||||||
"-Werror",
|
"-Werror",
|
||||||
"-O3",
|
"-O3",
|
||||||
|
"-ffast-math",
|
||||||
]
|
]
|
||||||
|
|
||||||
LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [
|
LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [
|
||||||
|
@@ -55,14 +55,15 @@ float YGFloatSanitize(const float val) {
|
|||||||
return yoga::isUndefined(val) ? 0 : val;
|
return yoga::isUndefined(val) ? 0 : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float YGUnwrapFloatOptional(const YGFloatOptional& op) {
|
||||||
|
return op.isUndefined() ? YGUndefined : op.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
YGFloatOptional YGFloatOptionalMax(
|
YGFloatOptional YGFloatOptionalMax(
|
||||||
const YGFloatOptional op1,
|
const YGFloatOptional& op1,
|
||||||
const YGFloatOptional op2) {
|
const YGFloatOptional& op2) {
|
||||||
if (op1 > op2) {
|
if (!op1.isUndefined() && !op2.isUndefined()) {
|
||||||
return op1;
|
return op1.getValue() > op2.getValue() ? op1 : op2;
|
||||||
}
|
|
||||||
if (op2 > op1) {
|
|
||||||
return op2;
|
|
||||||
}
|
}
|
||||||
return op1.isUndefined() ? op2 : op1;
|
return op1.isUndefined() ? op2 : op1;
|
||||||
}
|
}
|
||||||
|
36
yoga/Utils.h
36
yoga/Utils.h
@@ -57,12 +57,22 @@ bool YGValueEqual(const YGValue a, const YGValue b);
|
|||||||
// difference between two floats is less than 0.0001f or both are undefined.
|
// difference between two floats is less than 0.0001f or both are undefined.
|
||||||
bool YGFloatsEqual(const float a, const float b);
|
bool YGFloatsEqual(const float a, const float b);
|
||||||
|
|
||||||
|
// We need custom max function, since we want that, if one argument is
|
||||||
|
// YGUndefined then the max funtion should return the other argument as the max
|
||||||
|
// value. We wouldn't have needed a custom max function if YGUndefined was NAN
|
||||||
|
// as fmax has the same behaviour, but with NAN we cannot use `-ffast-math`
|
||||||
|
// compiler flag.
|
||||||
float YGFloatMax(const float a, const float b);
|
float YGFloatMax(const float a, const float b);
|
||||||
|
|
||||||
YGFloatOptional YGFloatOptionalMax(
|
YGFloatOptional YGFloatOptionalMax(
|
||||||
const YGFloatOptional op1,
|
const YGFloatOptional& op1,
|
||||||
const YGFloatOptional op2);
|
const YGFloatOptional& op2);
|
||||||
|
|
||||||
|
// We need custom min function, since we want that, if one argument is
|
||||||
|
// YGUndefined then the min funtion should return the other argument as the min
|
||||||
|
// value. We wouldn't have needed a custom min function if YGUndefined was NAN
|
||||||
|
// as fmin has the same behaviour, but with NAN we cannot use `-ffast-math`
|
||||||
|
// compiler flag.
|
||||||
float YGFloatMin(const float a, const float b);
|
float YGFloatMin(const float a, const float b);
|
||||||
|
|
||||||
// This custom float comparision function compares the array of float with
|
// This custom float comparision function compares the array of float with
|
||||||
@@ -82,6 +92,11 @@ bool YGFloatArrayEqual(
|
|||||||
// This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise
|
// This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise
|
||||||
float YGFloatSanitize(const float val);
|
float YGFloatSanitize(const float val);
|
||||||
|
|
||||||
|
// This function unwraps optional and returns YGUndefined if not defined or
|
||||||
|
// op.value otherwise
|
||||||
|
// TODO: Get rid off this function
|
||||||
|
float YGUnwrapFloatOptional(const YGFloatOptional& op);
|
||||||
|
|
||||||
YGFlexDirection YGFlexDirectionCross(
|
YGFlexDirection YGFlexDirectionCross(
|
||||||
const YGFlexDirection flexDirection,
|
const YGFlexDirection flexDirection,
|
||||||
const YGDirection direction);
|
const YGDirection direction);
|
||||||
@@ -91,17 +106,18 @@ inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) {
|
|||||||
flexDirection == YGFlexDirectionRowReverse;
|
flexDirection == YGFlexDirectionRowReverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline YGFloatOptional YGResolveValue(
|
inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) {
|
||||||
const YGValue value,
|
|
||||||
const float ownerSize) {
|
|
||||||
switch (value.unit) {
|
switch (value.unit) {
|
||||||
|
case YGUnitUndefined:
|
||||||
|
case YGUnitAuto:
|
||||||
|
return YGFloatOptional();
|
||||||
case YGUnitPoint:
|
case YGUnitPoint:
|
||||||
return YGFloatOptional{value.value};
|
return YGFloatOptional(value.value);
|
||||||
case YGUnitPercent:
|
case YGUnitPercent:
|
||||||
return YGFloatOptional{value.value * ownerSize * 0.01f};
|
return YGFloatOptional(
|
||||||
default:
|
static_cast<float>(value.value * ownerSize * 0.01));
|
||||||
return YGFloatOptional{};
|
|
||||||
}
|
}
|
||||||
|
return YGFloatOptional();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) {
|
inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) {
|
||||||
@@ -123,7 +139,7 @@ inline YGFlexDirection YGResolveFlexDirection(
|
|||||||
return flexDirection;
|
return flexDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline YGFloatOptional YGResolveValueMargin(
|
static inline YGFloatOptional YGResolveValueMargin(
|
||||||
const YGValue value,
|
const YGValue value,
|
||||||
const float ownerSize) {
|
const float ownerSize) {
|
||||||
return value.unit == YGUnitAuto ? YGFloatOptional(0)
|
return value.unit == YGUnitAuto ? YGFloatOptional(0)
|
||||||
|
83
yoga/YGFloatOptional.cpp
Normal file
83
yoga/YGFloatOptional.cpp
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
|
* file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
#include "YGFloatOptional.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include "Yoga.h"
|
||||||
|
#include "Yoga-internal.h"
|
||||||
|
|
||||||
|
using namespace facebook;
|
||||||
|
|
||||||
|
YGFloatOptional::YGFloatOptional(float value) {
|
||||||
|
if (yoga::isUndefined(value)) {
|
||||||
|
isUndefined_ = true;
|
||||||
|
value_ = 0;
|
||||||
|
} else {
|
||||||
|
value_ = value;
|
||||||
|
isUndefined_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float YGFloatOptional::getValue() const {
|
||||||
|
if (isUndefined_) {
|
||||||
|
// Abort, accessing a value of an undefined float optional
|
||||||
|
std::cerr << "Tried to get value of an undefined YGFloatOptional\n";
|
||||||
|
std::exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator==(const YGFloatOptional& op) const {
|
||||||
|
if (isUndefined_ == op.isUndefined()) {
|
||||||
|
return isUndefined_ || value_ == op.getValue();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator!=(const YGFloatOptional& op) const {
|
||||||
|
return !(*this == op);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator==(float val) const {
|
||||||
|
if (yoga::isUndefined(val) == isUndefined_) {
|
||||||
|
return isUndefined_ || val == value_;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator!=(float val) const {
|
||||||
|
return !(*this == val);
|
||||||
|
}
|
||||||
|
|
||||||
|
YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) {
|
||||||
|
if (!isUndefined_ && !op.isUndefined_) {
|
||||||
|
return YGFloatOptional(value_ + op.value_);
|
||||||
|
}
|
||||||
|
return YGFloatOptional();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator>(const YGFloatOptional& op) const {
|
||||||
|
if (isUndefined_ || op.isUndefined_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value_ > op.value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator<(const YGFloatOptional& op) const {
|
||||||
|
if (isUndefined_ || op.isUndefined_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value_ < op.value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator>=(const YGFloatOptional& op) const {
|
||||||
|
return *this == op || *this > op;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatOptional::operator<=(const YGFloatOptional& op) const {
|
||||||
|
return *this == op || *this < op;
|
||||||
|
}
|
@@ -6,68 +6,38 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include "Yoga-internal.h"
|
|
||||||
|
|
||||||
struct YGFloatOptional {
|
struct YGFloatOptional {
|
||||||
private:
|
private:
|
||||||
float value_ = std::numeric_limits<float>::quiet_NaN();
|
float value_ = 0;
|
||||||
|
bool isUndefined_ = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit constexpr YGFloatOptional(float value) : value_(value) {}
|
explicit YGFloatOptional(float value);
|
||||||
constexpr YGFloatOptional() = default;
|
YGFloatOptional() = default;
|
||||||
|
|
||||||
// returns the wrapped value, or a value x with YGIsUndefined(x) == true
|
// Program will terminate if the value of an undefined is accessed. Please
|
||||||
constexpr float unwrap() const {
|
// make sure to check if the optional is defined before calling this function.
|
||||||
return value_;
|
// To check if float optional is defined, use `isUndefined()`.
|
||||||
|
float getValue() const;
|
||||||
|
|
||||||
|
// Sets the value of float optional, and thus isUndefined is assigned false.
|
||||||
|
void setValue(float val) {
|
||||||
|
value_ = val;
|
||||||
|
isUndefined_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool isUndefined() const {
|
bool isUndefined() const {
|
||||||
// std::isnan is not constexpr
|
return isUndefined_;
|
||||||
return !(value_ == value_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr float orElse(float other) const {
|
YGFloatOptional operator+(const YGFloatOptional& op);
|
||||||
return isUndefined() ? other : value_;
|
bool operator>(const YGFloatOptional& op) const;
|
||||||
}
|
bool operator<(const YGFloatOptional& op) const;
|
||||||
|
bool operator>=(const YGFloatOptional& op) const;
|
||||||
|
bool operator<=(const YGFloatOptional& op) const;
|
||||||
|
bool operator==(const YGFloatOptional& op) const;
|
||||||
|
bool operator!=(const YGFloatOptional& op) const;
|
||||||
|
|
||||||
template <typename Factory>
|
bool operator==(float val) const;
|
||||||
constexpr float orElseGet(Factory&& f) const {
|
bool operator!=(float val) const;
|
||||||
return isUndefined() ? f() : value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
YGFloatOptional operator-() const {
|
|
||||||
return YGFloatOptional{-value_};
|
|
||||||
}
|
|
||||||
YGFloatOptional operator+(YGFloatOptional op) const {
|
|
||||||
return YGFloatOptional{value_ + op.value_};
|
|
||||||
}
|
|
||||||
YGFloatOptional operator-(YGFloatOptional op) const {
|
|
||||||
return YGFloatOptional{value_ - op.value_};
|
|
||||||
}
|
|
||||||
bool operator>(YGFloatOptional op) const {
|
|
||||||
return value_ > op.value_;
|
|
||||||
}
|
|
||||||
bool operator<(YGFloatOptional op) const {
|
|
||||||
return value_ < op.value_;
|
|
||||||
}
|
|
||||||
bool operator>=(YGFloatOptional op) const {
|
|
||||||
return *this > op || *this == op;
|
|
||||||
}
|
|
||||||
bool operator<=(YGFloatOptional op) const {
|
|
||||||
return *this < op || *this == op;
|
|
||||||
}
|
|
||||||
bool operator==(YGFloatOptional op) const {
|
|
||||||
return value_ == op.value_ || (isUndefined() && op.isUndefined());
|
|
||||||
}
|
|
||||||
bool operator!=(YGFloatOptional op) const {
|
|
||||||
return !(*this == op);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(float val) const {
|
|
||||||
return value_ == val || (isUndefined() && yoga::isUndefined(val));
|
|
||||||
}
|
|
||||||
bool operator!=(float val) const {
|
|
||||||
return !(*this == val);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@@ -175,7 +175,7 @@ void YGNode::setLayoutLastOwnerDirection(YGDirection direction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void YGNode::setLayoutComputedFlexBasis(
|
void YGNode::setLayoutComputedFlexBasis(
|
||||||
const YGFloatOptional computedFlexBasis) {
|
const YGFloatOptional& computedFlexBasis) {
|
||||||
layout_.computedFlexBasis = computedFlexBasis;
|
layout_.computedFlexBasis = computedFlexBasis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,11 @@ YGFloatOptional YGNode::relativePosition(
|
|||||||
return getLeadingPosition(axis, axisSize);
|
return getLeadingPosition(axis, axisSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -getTrailingPosition(axis, axisSize);
|
YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize);
|
||||||
|
if (!trailingPosition.isUndefined()) {
|
||||||
|
trailingPosition.setValue(-1 * trailingPosition.getValue());
|
||||||
|
}
|
||||||
|
return trailingPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void YGNode::setPosition(
|
void YGNode::setPosition(
|
||||||
@@ -232,18 +236,20 @@ void YGNode::setPosition(
|
|||||||
relativePosition(crossAxis, crossSize);
|
relativePosition(crossAxis, crossSize);
|
||||||
|
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
YGUnwrapFloatOptional(
|
||||||
|
getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain),
|
||||||
leading[mainAxis]);
|
leading[mainAxis]);
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
YGUnwrapFloatOptional(
|
||||||
|
getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain),
|
||||||
trailing[mainAxis]);
|
trailing[mainAxis]);
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
YGUnwrapFloatOptional(
|
||||||
.unwrap(),
|
getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross),
|
||||||
leading[crossAxis]);
|
leading[crossAxis]);
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
YGUnwrapFloatOptional(
|
||||||
.unwrap(),
|
getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross),
|
||||||
trailing[crossAxis]);
|
trailing[crossAxis]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +304,7 @@ YGValue YGNode::resolveFlexBasisPtr() const {
|
|||||||
if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) {
|
if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) {
|
||||||
return flexBasis;
|
return flexBasis;
|
||||||
}
|
}
|
||||||
if (style_.flex > YGFloatOptional{0.0f}) {
|
if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) {
|
||||||
return config_->useWebDefaults ? YGValueAuto : YGValueZero;
|
return config_->useWebDefaults ? YGValueAuto : YGValueZero;
|
||||||
}
|
}
|
||||||
return YGValueAuto;
|
return YGValueAuto;
|
||||||
@@ -388,23 +394,27 @@ float YGNode::resolveFlexGrow() {
|
|||||||
if (owner_ == nullptr) {
|
if (owner_ == nullptr) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
if (!style_.flexGrow.isUndefined()) {
|
||||||
return style_.flexGrow.orElseGet(
|
return style_.flexGrow.getValue();
|
||||||
[this] { return style_.flex.orElse(kDefaultFlexGrow); });
|
}
|
||||||
|
if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) {
|
||||||
|
return style_.flex.getValue();
|
||||||
|
}
|
||||||
|
return kDefaultFlexGrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
float YGNode::resolveFlexShrink() {
|
float YGNode::resolveFlexShrink() {
|
||||||
if (owner_ == nullptr) {
|
if (owner_ == nullptr) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
return style_.flexShrink.orElseGet([this] {
|
if (!style_.flexShrink.isUndefined()) {
|
||||||
if (style_.flex < YGFloatOptional{0.0f} && !config_->useWebDefaults) {
|
return style_.flexShrink.getValue();
|
||||||
return -style_.flex.unwrap();
|
}
|
||||||
} else {
|
if (!config_->useWebDefaults && !style_.flex.isUndefined() &&
|
||||||
return config_->useWebDefaults ? kWebDefaultFlexShrink
|
style_.flex.getValue() < 0.0f) {
|
||||||
: kDefaultFlexShrink;
|
return -style_.flex.getValue();
|
||||||
}
|
}
|
||||||
});
|
return config_->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGNode::isNodeFlexible() {
|
bool YGNode::isNodeFlexible() {
|
||||||
@@ -443,9 +453,11 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
|
|||||||
YGFloatOptional YGNode::getLeadingPadding(
|
YGFloatOptional YGNode::getLeadingPadding(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
const YGFloatOptional paddingEdgeStart =
|
const YGFloatOptional& paddingEdgeStart =
|
||||||
YGResolveValue(style_.padding[YGEdgeStart], widthSize);
|
YGResolveValue(style_.padding[YGEdgeStart], widthSize);
|
||||||
if (YGFlexDirectionIsRow(axis) && paddingEdgeStart >= YGFloatOptional{0.0f}) {
|
if (YGFlexDirectionIsRow(axis) &&
|
||||||
|
style_.padding[YGEdgeStart].unit != YGUnitUndefined &&
|
||||||
|
!paddingEdgeStart.isUndefined() && paddingEdgeStart.getValue() >= 0.0f) {
|
||||||
return paddingEdgeStart;
|
return paddingEdgeStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,10 +470,11 @@ YGFloatOptional YGNode::getLeadingPadding(
|
|||||||
YGFloatOptional YGNode::getTrailingPadding(
|
YGFloatOptional YGNode::getTrailingPadding(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
const YGFloatOptional paddingEdgeEnd =
|
if (YGFlexDirectionIsRow(axis) &&
|
||||||
YGResolveValue(style_.padding[YGEdgeEnd], widthSize);
|
style_.padding[YGEdgeEnd].unit != YGUnitUndefined &&
|
||||||
if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) {
|
!YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() &&
|
||||||
return paddingEdgeEnd;
|
YGResolveValue(style_.padding[YGEdgeEnd], widthSize).getValue() >= 0.0f) {
|
||||||
|
return YGResolveValue(style_.padding[YGEdgeEnd], widthSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional resolvedValue = YGResolveValue(
|
YGFloatOptional resolvedValue = YGResolveValue(
|
||||||
|
@@ -235,7 +235,7 @@ struct YGNode {
|
|||||||
|
|
||||||
void setDirty(bool isDirty);
|
void setDirty(bool isDirty);
|
||||||
void setLayoutLastOwnerDirection(YGDirection direction);
|
void setLayoutLastOwnerDirection(YGDirection direction);
|
||||||
void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis);
|
void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis);
|
||||||
void setLayoutComputedFlexBasisGeneration(
|
void setLayoutComputedFlexBasisGeneration(
|
||||||
uint32_t computedFlexBasisGeneration);
|
uint32_t computedFlexBasisGeneration);
|
||||||
void setLayoutMeasuredDimension(float measuredDimension, int index);
|
void setLayoutMeasuredDimension(float measuredDimension, int index);
|
||||||
|
@@ -14,9 +14,9 @@ namespace facebook {
|
|||||||
namespace yoga {
|
namespace yoga {
|
||||||
typedef std::string string;
|
typedef std::string string;
|
||||||
|
|
||||||
static void indent(string& base, uint32_t level) {
|
static void indent(string* base, uint32_t level) {
|
||||||
for (uint32_t i = 0; i < level; ++i) {
|
for (uint32_t i = 0; i < level; ++i) {
|
||||||
base.append(" ");
|
base->append(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ static bool areFourValuesEqual(const std::array<YGValue, YGEdgeCount>& four) {
|
|||||||
YGValueEqual(four[0], four[3]);
|
YGValueEqual(four[0], four[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void appendFormatedString(string& str, const char* fmt, ...) {
|
static void appendFormatedString(string* str, const char* fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
va_list argsCopy;
|
va_list argsCopy;
|
||||||
@@ -35,25 +35,25 @@ static void appendFormatedString(string& str, const char* fmt, ...) {
|
|||||||
vsnprintf(buf.data(), buf.size(), fmt, argsCopy);
|
vsnprintf(buf.data(), buf.size(), fmt, argsCopy);
|
||||||
va_end(argsCopy);
|
va_end(argsCopy);
|
||||||
string result = string(buf.begin(), buf.end() - 1);
|
string result = string(buf.begin(), buf.end() - 1);
|
||||||
str.append(result);
|
str->append(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void appendFloatOptionalIfDefined(
|
static void appendFloatOptionalIfDefined(
|
||||||
string& base,
|
string* base,
|
||||||
const string key,
|
const string key,
|
||||||
const YGFloatOptional num) {
|
const YGFloatOptional num) {
|
||||||
if (!num.isUndefined()) {
|
if (!num.isUndefined()) {
|
||||||
appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap());
|
appendFormatedString(base, "%s: %g; ", key.c_str(), num.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void appendNumberIfNotUndefined(
|
static void appendNumberIfNotUndefined(
|
||||||
string& base,
|
string* base,
|
||||||
const string key,
|
const string key,
|
||||||
const YGValue number) {
|
const YGValue number) {
|
||||||
if (number.unit != YGUnitUndefined) {
|
if (number.unit != YGUnitUndefined) {
|
||||||
if (number.unit == YGUnitAuto) {
|
if (number.unit == YGUnitAuto) {
|
||||||
base.append(key + ": auto; ");
|
base->append(key + ": auto; ");
|
||||||
} else {
|
} else {
|
||||||
string unit = number.unit == YGUnitPoint ? "px" : "%%";
|
string unit = number.unit == YGUnitPoint ? "px" : "%%";
|
||||||
appendFormatedString(
|
appendFormatedString(
|
||||||
@@ -63,23 +63,24 @@ static void appendNumberIfNotUndefined(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
appendNumberIfNotAuto(string& base, const string& key, const YGValue number) {
|
appendNumberIfNotAuto(string* base, const string& key, const YGValue number) {
|
||||||
if (number.unit != YGUnitAuto) {
|
if (number.unit != YGUnitAuto) {
|
||||||
appendNumberIfNotUndefined(base, key, number);
|
appendNumberIfNotUndefined(base, key, number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
appendNumberIfNotZero(string& base, const string& str, const YGValue number) {
|
appendNumberIfNotZero(string* base, const string& str, const YGValue number) {
|
||||||
|
|
||||||
if (number.unit == YGUnitAuto) {
|
if (number.unit == YGUnitAuto) {
|
||||||
base.append(str + ": auto; ");
|
base->append(str + ": auto; ");
|
||||||
} else if (!YGFloatsEqual(number.value, 0)) {
|
} else if (!YGFloatsEqual(number.value, 0)) {
|
||||||
appendNumberIfNotUndefined(base, str, number);
|
appendNumberIfNotUndefined(base, str, number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void appendEdges(
|
static void appendEdges(
|
||||||
string& base,
|
string* base,
|
||||||
const string& key,
|
const string& key,
|
||||||
const std::array<YGValue, YGEdgeCount>& edges) {
|
const std::array<YGValue, YGEdgeCount>& edges) {
|
||||||
if (areFourValuesEqual(edges)) {
|
if (areFourValuesEqual(edges)) {
|
||||||
@@ -93,7 +94,7 @@ static void appendEdges(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void appendEdgeIfNotUndefined(
|
static void appendEdgeIfNotUndefined(
|
||||||
string& base,
|
string* base,
|
||||||
const string& str,
|
const string& str,
|
||||||
const std::array<YGValue, YGEdgeCount>& edges,
|
const std::array<YGValue, YGEdgeCount>& edges,
|
||||||
const YGEdge edge) {
|
const YGEdge edge) {
|
||||||
@@ -102,7 +103,7 @@ static void appendEdgeIfNotUndefined(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void YGNodeToString(
|
void YGNodeToString(
|
||||||
std::string& str,
|
std::string* str,
|
||||||
YGNodeRef node,
|
YGNodeRef node,
|
||||||
YGPrintOptions options,
|
YGPrintOptions options,
|
||||||
uint32_t level) {
|
uint32_t level) {
|
||||||
|
@@ -13,7 +13,7 @@ namespace facebook {
|
|||||||
namespace yoga {
|
namespace yoga {
|
||||||
|
|
||||||
void YGNodeToString(
|
void YGNodeToString(
|
||||||
std::string& str,
|
std::string* str,
|
||||||
YGNodeRef node,
|
YGNodeRef node,
|
||||||
YGPrintOptions options,
|
YGPrintOptions options,
|
||||||
uint32_t level);
|
uint32_t level);
|
||||||
|
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
// Yoga specific properties, not compatible with flexbox specification
|
// Yoga specific properties, not compatible with flexbox specification
|
||||||
bool YGStyle::operator==(const YGStyle& style) {
|
bool YGStyle::operator==(const YGStyle& style) {
|
||||||
return (
|
bool areNonFloatValuesEqual = direction == style.direction &&
|
||||||
direction == style.direction && flexDirection == style.flexDirection &&
|
flexDirection == style.flexDirection &&
|
||||||
justifyContent == style.justifyContent &&
|
justifyContent == style.justifyContent &&
|
||||||
alignContent == style.alignContent && alignItems == style.alignItems &&
|
alignContent == style.alignContent && alignItems == style.alignItems &&
|
||||||
alignSelf == style.alignSelf && positionType == style.positionType &&
|
alignSelf == style.alignSelf && positionType == style.positionType &&
|
||||||
@@ -21,7 +21,34 @@ bool YGStyle::operator==(const YGStyle& style) {
|
|||||||
YGValueArrayEqual(border, style.border) &&
|
YGValueArrayEqual(border, style.border) &&
|
||||||
YGValueArrayEqual(dimensions, style.dimensions) &&
|
YGValueArrayEqual(dimensions, style.dimensions) &&
|
||||||
YGValueArrayEqual(minDimensions, style.minDimensions) &&
|
YGValueArrayEqual(minDimensions, style.minDimensions) &&
|
||||||
YGValueArrayEqual(maxDimensions, style.maxDimensions) &&
|
YGValueArrayEqual(maxDimensions, style.maxDimensions);
|
||||||
flex == style.flex && flexGrow == style.flexGrow &&
|
|
||||||
flexShrink == style.flexShrink && aspectRatio == style.aspectRatio);
|
areNonFloatValuesEqual =
|
||||||
|
areNonFloatValuesEqual && flex.isUndefined() == style.flex.isUndefined();
|
||||||
|
if (areNonFloatValuesEqual && !flex.isUndefined() &&
|
||||||
|
!style.flex.isUndefined()) {
|
||||||
|
areNonFloatValuesEqual =
|
||||||
|
areNonFloatValuesEqual && flex.getValue() == style.flex.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
flexGrow.isUndefined() == style.flexGrow.isUndefined();
|
||||||
|
if (areNonFloatValuesEqual && !flexGrow.isUndefined()) {
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
flexGrow.getValue() == style.flexGrow.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
flexShrink.isUndefined() == style.flexShrink.isUndefined();
|
||||||
|
if (areNonFloatValuesEqual && !style.flexShrink.isUndefined()) {
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
flexShrink.getValue() == style.flexShrink.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) {
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
aspectRatio.getValue() == style.aspectRatio.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return areNonFloatValuesEqual;
|
||||||
}
|
}
|
||||||
|
@@ -30,16 +30,16 @@ constexpr std::array<YGValue, 2> kYGDefaultDimensionValuesUnit = {
|
|||||||
struct YGStyle {
|
struct YGStyle {
|
||||||
using Dimensions = std::array<YGValue, 2>;
|
using Dimensions = std::array<YGValue, 2>;
|
||||||
|
|
||||||
YGDirection direction : 2;
|
YGDirection direction = YGDirectionInherit;
|
||||||
YGFlexDirection flexDirection : 2;
|
YGFlexDirection flexDirection = YGFlexDirectionColumn;
|
||||||
YGJustify justifyContent : 3;
|
YGJustify justifyContent = YGJustifyFlexStart;
|
||||||
YGAlign alignContent : 3;
|
YGAlign alignContent = YGAlignFlexStart;
|
||||||
YGAlign alignItems : 3;
|
YGAlign alignItems = YGAlignStretch;
|
||||||
YGAlign alignSelf : 3;
|
YGAlign alignSelf = YGAlignAuto;
|
||||||
YGPositionType positionType : 1;
|
YGPositionType positionType = YGPositionTypeRelative;
|
||||||
YGWrap flexWrap : 2;
|
YGWrap flexWrap = YGWrapNoWrap;
|
||||||
YGOverflow overflow : 2;
|
YGOverflow overflow = YGOverflowVisible;
|
||||||
YGDisplay display : 1;
|
YGDisplay display = YGDisplayFlex;
|
||||||
YGFloatOptional flex = {};
|
YGFloatOptional flex = {};
|
||||||
YGFloatOptional flexGrow = {};
|
YGFloatOptional flexGrow = {};
|
||||||
YGFloatOptional flexShrink = {};
|
YGFloatOptional flexShrink = {};
|
||||||
@@ -54,17 +54,7 @@ struct YGStyle {
|
|||||||
// Yoga specific properties, not compatible with flexbox specification
|
// Yoga specific properties, not compatible with flexbox specification
|
||||||
YGFloatOptional aspectRatio = {};
|
YGFloatOptional aspectRatio = {};
|
||||||
|
|
||||||
YGStyle()
|
YGStyle() = default;
|
||||||
: direction(YGDirectionInherit),
|
|
||||||
flexDirection(YGFlexDirectionColumn),
|
|
||||||
justifyContent(YGJustifyFlexStart),
|
|
||||||
alignContent(YGAlignFlexStart),
|
|
||||||
alignItems(YGAlignStretch),
|
|
||||||
alignSelf(YGAlignAuto),
|
|
||||||
positionType(YGPositionTypeRelative),
|
|
||||||
flexWrap(YGWrapNoWrap),
|
|
||||||
overflow(YGOverflowVisible),
|
|
||||||
display(YGDisplayFlex) {}
|
|
||||||
bool operator==(const YGStyle& style);
|
bool operator==(const YGStyle& style);
|
||||||
|
|
||||||
bool operator!=(YGStyle style) {
|
bool operator!=(YGStyle style) {
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the LICENSE
|
|
||||||
* file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
#include "YGValue.h"
|
|
||||||
|
|
||||||
const YGValue YGValueZero = {0, YGUnitPoint};
|
|
||||||
const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined};
|
|
||||||
const YGValue YGValueAuto = {YGUndefined, YGUnitAuto};
|
|
@@ -1,56 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the LICENSE
|
|
||||||
* file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include "YGEnums.h"
|
|
||||||
#include "YGMacros.h"
|
|
||||||
|
|
||||||
YG_EXTERN_C_BEGIN
|
|
||||||
|
|
||||||
// Not defined in MSVC++
|
|
||||||
#ifndef NAN
|
|
||||||
static const uint32_t __nan = 0x7fc00000;
|
|
||||||
#define NAN (*(const float*)__nan)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define YGUndefined NAN
|
|
||||||
|
|
||||||
typedef struct YGValue {
|
|
||||||
float value;
|
|
||||||
YGUnit unit;
|
|
||||||
} YGValue;
|
|
||||||
|
|
||||||
extern const YGValue YGValueAuto;
|
|
||||||
extern const YGValue YGValueUndefined;
|
|
||||||
extern const YGValue YGValueZero;
|
|
||||||
|
|
||||||
YG_EXTERN_C_END
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
inline bool operator==(const YGValue& lhs, const YGValue& rhs) {
|
|
||||||
if (lhs.unit != rhs.unit) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (lhs.unit) {
|
|
||||||
case YGUnitUndefined:
|
|
||||||
case YGUnitAuto:
|
|
||||||
return true;
|
|
||||||
case YGUnitPoint:
|
|
||||||
case YGUnitPercent:
|
|
||||||
default:
|
|
||||||
return lhs.value == rhs.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const YGValue& lhs, const YGValue& rhs) {
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@@ -27,7 +27,15 @@ namespace facebook {
|
|||||||
namespace yoga {
|
namespace yoga {
|
||||||
|
|
||||||
inline bool isUndefined(float value) {
|
inline bool isUndefined(float value) {
|
||||||
return std::isnan(value);
|
// Value of a float in the case of it being not defined is 10.1E20. Earlier
|
||||||
|
// it used to be NAN, the benefit of which was that if NAN is involved in any
|
||||||
|
// mathematical expression the result was NAN. But since we want to have
|
||||||
|
// `-ffast-math` flag being used by compiler which assumes that the floating
|
||||||
|
// point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But
|
||||||
|
// now if YGUndefined is involved in any mathematical operations this
|
||||||
|
// value(10.1E20) would change. So the following check makes sure that if the
|
||||||
|
// value is outside a range (-10E8, 10E8) then it is undefined.
|
||||||
|
return value >= 10E8 || value <= -10E8;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace yoga
|
} // namespace yoga
|
||||||
|
569
yoga/Yoga.cpp
569
yoga/Yoga.cpp
File diff suppressed because it is too large
Load Diff
29
yoga/Yoga.h
29
yoga/Yoga.h
@@ -17,9 +17,17 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Large positive number signifies that the property(float) is undefined.
|
||||||
|
*Earlier we used to have YGundefined as NAN, but the downside of this is that
|
||||||
|
*we can't use -ffast-math compiler flag as it assumes all floating-point
|
||||||
|
*calculation involve and result into finite numbers. For more information
|
||||||
|
*regarding -ffast-math compiler flag in clang, have a look at
|
||||||
|
*https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math
|
||||||
|
**/
|
||||||
|
#define YGUndefined 10E20F
|
||||||
|
|
||||||
#include "YGEnums.h"
|
#include "YGEnums.h"
|
||||||
#include "YGMacros.h"
|
#include "YGMacros.h"
|
||||||
#include "YGValue.h"
|
|
||||||
|
|
||||||
YG_EXTERN_C_BEGIN
|
YG_EXTERN_C_BEGIN
|
||||||
|
|
||||||
@@ -28,6 +36,25 @@ typedef struct YGSize {
|
|||||||
float height;
|
float height;
|
||||||
} YGSize;
|
} YGSize;
|
||||||
|
|
||||||
|
typedef struct YGValue {
|
||||||
|
float value;
|
||||||
|
YGUnit unit;
|
||||||
|
} YGValue;
|
||||||
|
|
||||||
|
extern const YGValue YGValueUndefined;
|
||||||
|
extern const YGValue YGValueAuto;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
YG_EXTERN_C_END
|
||||||
|
|
||||||
|
extern bool operator==(const YGValue& lhs, const YGValue& rhs);
|
||||||
|
extern bool operator!=(const YGValue& lhs, const YGValue& rhs);
|
||||||
|
|
||||||
|
YG_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct YGConfig* YGConfigRef;
|
typedef struct YGConfig* YGConfigRef;
|
||||||
|
|
||||||
typedef struct YGNode* YGNodeRef;
|
typedef struct YGNode* YGNodeRef;
|
||||||
|
Reference in New Issue
Block a user