Store YGFloatOptional
in 32 bits
Summary: @public After removing `-ffast-math`, `NaN` can again be used to represent `undefined`. That allows us to remove the additional flag from `YGFloatOptional`, and reduce memory usage. Reviewed By: SidharthGuglani Differential Revision: D13209157 fbshipit-source-id: 21b83c837a78f924a4ec23a9236ca2440b3c8606
This commit is contained in:
committed by
Facebook Github Bot
parent
ed5c5a799f
commit
ed3b54b603
163
tests/YGFloatOptionalTest.cpp
Normal file
163
tests/YGFloatOptionalTest.cpp
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/**
|
||||||
|
* 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/YGValue.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.getValue(), 0.0f);
|
||||||
|
ASSERT_EQ(positive.getValue(), 1234.5f);
|
||||||
|
ASSERT_EQ(negative.getValue(), -9876.5f);
|
||||||
|
|
||||||
|
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.getValue());
|
||||||
|
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.getValue());
|
||||||
|
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_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_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.getValue() + positive.getValue()});
|
||||||
|
ASSERT_EQ(empty + zero, empty);
|
||||||
|
ASSERT_EQ(empty + empty, empty);
|
||||||
|
ASSERT_EQ(negative + empty, empty);
|
||||||
|
}
|
@@ -7,23 +7,13 @@
|
|||||||
#include "YGFloatOptional.h"
|
#include "YGFloatOptional.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Yoga.h"
|
|
||||||
#include "Yoga-internal.h"
|
#include "Yoga-internal.h"
|
||||||
|
#include "Yoga.h"
|
||||||
|
|
||||||
using namespace facebook;
|
using namespace facebook;
|
||||||
|
|
||||||
YGFloatOptional::YGFloatOptional(float value) {
|
|
||||||
if (yoga::isUndefined(value)) {
|
|
||||||
isUndefined_ = true;
|
|
||||||
value_ = 0;
|
|
||||||
} else {
|
|
||||||
value_ = value;
|
|
||||||
isUndefined_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float YGFloatOptional::getValue() const {
|
float YGFloatOptional::getValue() const {
|
||||||
if (isUndefined_) {
|
if (isUndefined()) {
|
||||||
// Abort, accessing a value of an undefined float optional
|
// Abort, accessing a value of an undefined float optional
|
||||||
std::cerr << "Tried to get value of an undefined YGFloatOptional\n";
|
std::cerr << "Tried to get value of an undefined YGFloatOptional\n";
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
@@ -31,53 +21,38 @@ float YGFloatOptional::getValue() const {
|
|||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator==(const YGFloatOptional& op) const {
|
bool YGFloatOptional::operator==(YGFloatOptional op) const {
|
||||||
if (isUndefined_ == op.isUndefined()) {
|
return value_ == op.value_ || (isUndefined() && op.isUndefined());
|
||||||
return isUndefined_ || value_ == op.getValue();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator!=(const YGFloatOptional& op) const {
|
bool YGFloatOptional::operator!=(YGFloatOptional op) const {
|
||||||
return !(*this == op);
|
return !(*this == op);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator==(float val) const {
|
bool YGFloatOptional::operator==(float val) const {
|
||||||
if (yoga::isUndefined(val) == isUndefined_) {
|
return value_ == val || (isUndefined() && yoga::isUndefined(val));
|
||||||
return isUndefined_ || val == value_;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator!=(float val) const {
|
bool YGFloatOptional::operator!=(float val) const {
|
||||||
return !(*this == val);
|
return !(*this == val);
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) {
|
YGFloatOptional YGFloatOptional::operator+(YGFloatOptional op) const {
|
||||||
if (!isUndefined_ && !op.isUndefined_) {
|
return YGFloatOptional{value_ + op.value_};
|
||||||
return YGFloatOptional(value_ + op.value_);
|
|
||||||
}
|
|
||||||
return YGFloatOptional();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator>(const YGFloatOptional& op) const {
|
bool YGFloatOptional::operator>(YGFloatOptional op) const {
|
||||||
if (isUndefined_ || op.isUndefined_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return value_ > op.value_;
|
return value_ > op.value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator<(const YGFloatOptional& op) const {
|
bool YGFloatOptional::operator<(YGFloatOptional op) const {
|
||||||
if (isUndefined_ || op.isUndefined_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return value_ < op.value_;
|
return value_ < op.value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator>=(const YGFloatOptional& op) const {
|
bool YGFloatOptional::operator>=(YGFloatOptional op) const {
|
||||||
return *this == op || *this > op;
|
return *this > op || *this == op;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGFloatOptional::operator<=(const YGFloatOptional& op) const {
|
bool YGFloatOptional::operator<=(YGFloatOptional op) const {
|
||||||
return *this == op || *this < op;
|
return *this < op || *this == op;
|
||||||
}
|
}
|
||||||
|
@@ -6,37 +6,33 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
struct YGFloatOptional {
|
struct YGFloatOptional {
|
||||||
private:
|
private:
|
||||||
float value_ = 0;
|
float value_ = std::numeric_limits<float>::quiet_NaN();
|
||||||
bool isUndefined_ = true;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit YGFloatOptional(float value);
|
explicit constexpr YGFloatOptional(float value) : value_(value) {}
|
||||||
YGFloatOptional() = default;
|
constexpr YGFloatOptional() = default;
|
||||||
|
|
||||||
// Program will terminate if the value of an undefined is accessed. Please
|
// Program will terminate if the value of an undefined is accessed. Please
|
||||||
// make sure to check if the optional is defined before calling this function.
|
// make sure to check if the optional is defined before calling this function.
|
||||||
// To check if float optional is defined, use `isUndefined()`.
|
// To check if float optional is defined, use `isUndefined()`.
|
||||||
float getValue() const;
|
float getValue() const;
|
||||||
|
|
||||||
// Sets the value of float optional, and thus isUndefined is assigned false.
|
|
||||||
void setValue(float val) {
|
|
||||||
value_ = val;
|
|
||||||
isUndefined_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isUndefined() const {
|
bool isUndefined() const {
|
||||||
return isUndefined_;
|
return std::isnan(value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional operator+(const YGFloatOptional& op);
|
YGFloatOptional operator+(YGFloatOptional op) const;
|
||||||
bool operator>(const YGFloatOptional& op) const;
|
bool operator>(YGFloatOptional op) const;
|
||||||
bool operator<(const YGFloatOptional& op) const;
|
bool operator<(YGFloatOptional op) const;
|
||||||
bool operator>=(const YGFloatOptional& op) const;
|
bool operator>=(YGFloatOptional op) const;
|
||||||
bool operator<=(const YGFloatOptional& op) const;
|
bool operator<=(YGFloatOptional op) const;
|
||||||
bool operator==(const YGFloatOptional& op) const;
|
bool operator==(YGFloatOptional op) const;
|
||||||
bool operator!=(const YGFloatOptional& op) const;
|
bool operator!=(YGFloatOptional op) const;
|
||||||
|
|
||||||
bool operator==(float val) const;
|
bool operator==(float val) const;
|
||||||
bool operator!=(float val) const;
|
bool operator!=(float val) const;
|
||||||
|
@@ -211,7 +211,7 @@ YGFloatOptional YGNode::relativePosition(
|
|||||||
|
|
||||||
YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize);
|
YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize);
|
||||||
if (!trailingPosition.isUndefined()) {
|
if (!trailingPosition.isUndefined()) {
|
||||||
trailingPosition.setValue(-1 * trailingPosition.getValue());
|
trailingPosition = YGFloatOptional{-1 * trailingPosition.getValue()};
|
||||||
}
|
}
|
||||||
return trailingPosition;
|
return trailingPosition;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user