diff --git a/enums.py b/enums.py index 749cb825af..ca1d98e8ab 100755 --- a/enums.py +++ b/enums.py @@ -131,10 +131,7 @@ def to_hyphenated_lower(symbol): f.write("YG_EXTERN_C_BEGIN\n\n") items = sorted(ENUMS.items()) for name, values in items: - if isinstance(values[0], tuple): - f.write("YG_ENUM_DECL(\n") - else: - f.write("YG_ENUM_SEQ_DECL(\n") + f.write("YG_ENUM_DECL(\n") f.write(" YG%s,\n" % name) for value in values: diff --git a/tests/NumericBitfieldTest.cpp b/tests/NumericBitfieldTest.cpp deleted file mode 100644 index 852267718d..0000000000 --- a/tests/NumericBitfieldTest.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include - -#include -#include - -namespace facebook::yoga { - -TEST(NumericBitfield, one_boolean_defaults_to_false) { - constexpr uint32_t flags = 0; - - ASSERT_EQ(getBooleanData(flags, 0), false); - static_assert( - getBooleanData(flags, 0) == false, - "first boolean member must default to false"); -} - -TEST(NumericBitfield, one_boolean_can_be_initialized_to_true) { - constexpr uint32_t flags = 1; - - ASSERT_EQ(getBooleanData(flags, 0), true); - static_assert( - getBooleanData(flags, 0) == true, - "first boolean member must be initialized to true"); -} - -TEST(NumericBitfield, one_boolean_can_be_set_to_true) { - uint32_t flags = 0; - - setBooleanData(flags, 0, true); - ASSERT_EQ(getBooleanData(flags, 0), true); -} - -TEST(NumericBitfield, second_boolean_defaults_to_false) { - constexpr uint32_t flags = 0; - - ASSERT_EQ(getBooleanData(flags, 1), false); - static_assert( - getBooleanData(flags, 1) == false, - "second boolean member must default to false"); -} - -TEST(NumericBitfield, second_boolean_can_be_initialized_to_true) { - constexpr uint32_t flags = 2; - - ASSERT_EQ(getBooleanData(flags, 0), false); - ASSERT_EQ(getBooleanData(flags, 1), true); - static_assert( - getBooleanData(flags, 0) == false, - "first boolean member must default to false"); - static_assert( - getBooleanData(flags, 1) == true, - "second boolean member must be initialized to true"); -} - -TEST(NumericBitfield, second_boolean_can_be_set_to_true) { - uint32_t flags = 0; - - setBooleanData(flags, 1, true); - ASSERT_EQ(getBooleanData(flags, 0), false); - ASSERT_EQ(getBooleanData(flags, 1), true); -} - -TEST(NumericBitfield, third_boolean_defaults_to_false) { - constexpr uint32_t flags = 0; - - ASSERT_EQ(getBooleanData(flags, 2), false); - static_assert( - getBooleanData(flags, 2) == false, - "second boolean member must default to false"); -} - -TEST(NumericBitfield, third_boolean_can_be_initialized_to_true) { - constexpr uint32_t flags = 4; - - ASSERT_EQ(getBooleanData(flags, 0), false); - ASSERT_EQ(getBooleanData(flags, 1), false); - ASSERT_EQ(getBooleanData(flags, 2), true); - static_assert( - getBooleanData(flags, 0) == false, - "first boolean member must default to false"); - static_assert( - getBooleanData(flags, 1) == false, - "second boolean member must default to false"); - static_assert( - getBooleanData(flags, 2) == true, - "second boolean member must be initialized to true"); -} - -TEST(NumericBitfield, third_boolean_can_be_set_to_true) { - uint32_t flags = 0; - - setBooleanData(flags, 2, true); - ASSERT_EQ(getBooleanData(flags, 0), false); - ASSERT_EQ(getBooleanData(flags, 1), false); - ASSERT_EQ(getBooleanData(flags, 2), true); -} - -TEST(NumericBitfield, setting_boolean_values_does_not_spill_over) { - uint32_t flags = 0; - - setBooleanData(flags, 1, (bool)7); - - ASSERT_EQ(getBooleanData(flags, 0), false); - ASSERT_EQ(getBooleanData(flags, 1), true); - ASSERT_EQ(getBooleanData(flags, 2), false); -} - -TEST(NumericBitfield, first_enum_defaults_to_0) { - constexpr uint32_t flags = 0; - - ASSERT_EQ(getEnumData(flags, 0), YGAlignAuto); - static_assert( - getEnumData(flags, 0) == YGAlignAuto, - "first enum member must default to 0"); -} - -TEST(NumericBitfield, first_enum_can_be_set) { - uint32_t flags = 0; - - setEnumData(flags, 0, YGAlignSpaceBetween); - - ASSERT_EQ(getEnumData(flags, 0), YGAlignSpaceBetween); -} - -TEST(NumericBitfield, second_enum_defaults_to_0) { - constexpr uint32_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgeOffset = 3; - - ASSERT_EQ(getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(getEnumData(flags, edgeOffset), YGEdgeLeft); - static_assert( - getEnumData(flags, alignOffset) == YGAlignAuto, - "first enum member must default to 0"); - static_assert( - getEnumData(flags, edgeOffset) == YGEdgeLeft, - "second enum member must default to 0"); -} - -TEST(NumericBitfield, second_enum_can_be_set) { - uint32_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgeOffset = 3; - - setEnumData(flags, edgeOffset, YGEdgeAll); - - ASSERT_EQ(getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(getEnumData(flags, edgeOffset), YGEdgeAll); -} - -TEST(NumericBitfield, third_enum_defaults_to_0) { - constexpr uint32_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t boolOffset = 3; - static constexpr size_t edgesOffset = 4; - - ASSERT_EQ(getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(getBooleanData(flags, boolOffset), false); - ASSERT_EQ(getEnumData(flags, edgesOffset), YGEdgeLeft); - static_assert( - getEnumData(flags, alignOffset) == YGAlignAuto, - "first enum member must default to 0"); - static_assert( - getBooleanData(flags, boolOffset) == false, - "middle boolean member must default to false"); - static_assert( - getEnumData(flags, edgesOffset) == YGEdgeLeft, - "last enum member must default to 0"); -} - -TEST(NumericBitfield, third_enum_can_be_set) { - uint32_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t boolOffset = 3; - static constexpr size_t edgesOffset = 4; - - setEnumData(flags, edgesOffset, YGEdgeVertical); - - ASSERT_EQ(getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(getBooleanData(flags, boolOffset), false); - ASSERT_EQ(getEnumData(flags, edgesOffset), YGEdgeVertical); -} - -TEST(NumericBitfield, setting_values_does_not_spill_over) { - uint32_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgesOffset = 4; - static constexpr size_t boolOffset = 8; - - uint32_t edge = 0xffffff; - setEnumData(flags, edgesOffset, (YGEdge)edge); - - ASSERT_EQ(getEnumData(flags, alignOffset), 0); - ASSERT_EQ(getBooleanData(flags, boolOffset), false); - ASSERT_EQ(getEnumData(flags, edgesOffset), 0xf); -} - -} // namespace facebook::yoga diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index e1197444db..e0454394da 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -12,7 +12,7 @@ YG_EXTERN_C_BEGIN -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGAlign, YGAlignAuto, YGAlignFlexStart, @@ -24,23 +24,23 @@ YG_ENUM_SEQ_DECL( YGAlignSpaceAround, YGAlignSpaceEvenly) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGDimension, YGDimensionWidth, YGDimensionHeight) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGDirection, YGDirectionInherit, YGDirectionLTR, YGDirectionRTL) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGDisplay, YGDisplayFlex, YGDisplayNone) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGEdge, YGEdgeLeft, YGEdgeTop, @@ -62,25 +62,25 @@ YG_ENUM_DECL( YGErrataClassic = 2147483646) YG_DEFINE_ENUM_FLAG_OPERATORS(YGErrata) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGFlexDirection, YGFlexDirectionColumn, YGFlexDirectionColumnReverse, YGFlexDirectionRow, YGFlexDirectionRowReverse) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGGutter, YGGutterColumn, YGGutterRow, YGGutterAll) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGJustify, YGJustifyFlexStart, YGJustifyCenter, @@ -89,7 +89,7 @@ YG_ENUM_SEQ_DECL( YGJustifySpaceAround, YGJustifySpaceEvenly) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGLogLevel, YGLogLevelError, YGLogLevelWarn, @@ -98,24 +98,24 @@ YG_ENUM_SEQ_DECL( YGLogLevelVerbose, YGLogLevelFatal) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGMeasureMode, YGMeasureModeUndefined, YGMeasureModeExactly, YGMeasureModeAtMost) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGNodeType, YGNodeTypeDefault, YGNodeTypeText) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGOverflow, YGOverflowVisible, YGOverflowHidden, YGOverflowScroll) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGPositionType, YGPositionTypeStatic, YGPositionTypeRelative, @@ -128,14 +128,14 @@ YG_ENUM_DECL( YGPrintOptionsChildren = 4) YG_DEFINE_ENUM_FLAG_OPERATORS(YGPrintOptions) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGUnit, YGUnitUndefined, YGUnitPoint, YGUnitPercent, YGUnitAuto) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGWrap, YGWrapNoWrap, YGWrapWrap, diff --git a/yoga/YGMacros.h b/yoga/YGMacros.h index 07ddb1903b..6460297a3d 100644 --- a/yoga/YGMacros.h +++ b/yoga/YGMacros.h @@ -88,40 +88,6 @@ #define YG_DEFINE_ENUM_FLAG_OPERATORS(name) #endif -#ifdef __cplusplus - -namespace facebook::yoga { - -template -constexpr int -ordinalCount(); // can't use `= delete` due to a defect in clang < 3.9 - -namespace detail { -template -constexpr int n() { - return sizeof...(xs); -} -} // namespace detail - -} // namespace facebook::yoga -#endif - #define YG_ENUM_DECL(NAME, ...) \ typedef YG_ENUM_BEGIN(NAME){__VA_ARGS__} YG_ENUM_END(NAME); \ YG_EXPORT const char* NAME##ToString(NAME); - -#ifdef __cplusplus -#define YG_ENUM_SEQ_DECL(NAME, ...) \ - YG_ENUM_DECL(NAME, __VA_ARGS__) \ - YG_EXTERN_C_END \ - \ - namespace facebook::yoga { \ - template <> \ - constexpr int ordinalCount() { \ - return detail::n<__VA_ARGS__>(); \ - } \ - } \ - YG_EXTERN_C_BEGIN -#else -#define YG_ENUM_SEQ_DECL YG_ENUM_DECL -#endif diff --git a/yoga/bits/NumericBitfield.h b/yoga/bits/NumericBitfield.h deleted file mode 100644 index d6102409b2..0000000000 --- a/yoga/bits/NumericBitfield.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and 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 -#include -#include -#include - -#include -#include - -namespace facebook::yoga::details { - -constexpr uint8_t log2ceilFn(uint8_t n) { - return n < 1 ? 0 : (1 + log2ceilFn(n / 2)); -} - -constexpr uint32_t mask(uint8_t bitWidth, uint8_t index) { - return ((1u << bitWidth) - 1u) << index; -} - -} // namespace facebook::yoga::details - -namespace facebook::yoga { - -// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL -template < - typename Enum, - std::enable_if_t<(ordinalCount() > 0), bool> = true> -constexpr uint8_t minimumBitCount() { - return details::log2ceilFn(static_cast(ordinalCount() - 1)); -} - -template -constexpr Enum getEnumData(uint32_t flags, uint8_t index) { - return static_cast( - (flags & details::mask(minimumBitCount(), index)) >> index); -} - -template -void setEnumData(uint32_t& flags, uint8_t index, Value newValue) { - flags = - (flags & - ~static_cast(details::mask(minimumBitCount(), index))) | - ((static_cast(newValue) << index) & - (details::mask(minimumBitCount(), index))); -} - -constexpr bool getBooleanData(uint32_t flags, uint8_t index) { - return (flags >> index) & 1; -} - -inline void setBooleanData(uint32_t& flags, uint8_t index, bool value) { - if (value) { - flags |= 1 << index; - } else { - flags &= ~(1 << index); - } -} - -} // namespace facebook::yoga diff --git a/yoga/node/LayoutResults.h b/yoga/node/LayoutResults.h index f7cf8b8cf4..819ec1e487 100644 --- a/yoga/node/LayoutResults.h +++ b/yoga/node/LayoutResults.h @@ -9,7 +9,6 @@ #include -#include #include #include #include diff --git a/yoga/style/Style.h b/yoga/style/Style.h index 74736d27b9..30f631f279 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -14,7 +14,6 @@ #include -#include #include #include #include @@ -55,123 +54,74 @@ class YG_EXPORT Style { static constexpr float DefaultFlexShrink = 0.0f; static constexpr float WebDefaultFlexShrink = 1.0f; - Style() { - setAlignContent(Align::FlexStart); - setAlignItems(Align::Stretch); - } - ~Style() = default; - - private: - using Dimensions = std::array()>; - using Edges = std::array()>; - using Gutters = std::array()>; - - static constexpr uint8_t directionOffset = 0; - static constexpr uint8_t flexdirectionOffset = - directionOffset + minimumBitCount(); - static constexpr uint8_t justifyContentOffset = - flexdirectionOffset + minimumBitCount(); - static constexpr uint8_t alignContentOffset = - justifyContentOffset + minimumBitCount(); - static constexpr uint8_t alignItemsOffset = - alignContentOffset + minimumBitCount(); - static constexpr uint8_t alignSelfOffset = - alignItemsOffset + minimumBitCount(); - static constexpr uint8_t positionTypeOffset = - alignSelfOffset + minimumBitCount(); - static constexpr uint8_t flexWrapOffset = - positionTypeOffset + minimumBitCount(); - static constexpr uint8_t overflowOffset = - flexWrapOffset + minimumBitCount(); - static constexpr uint8_t displayOffset = - overflowOffset + minimumBitCount(); - - uint32_t flags_ = 0; - - FloatOptional flex_ = {}; - FloatOptional flexGrow_ = {}; - FloatOptional flexShrink_ = {}; - Style::Length flexBasis_ = value::ofAuto(); - Edges margin_ = {}; - Edges position_ = {}; - Edges padding_ = {}; - Edges border_ = {}; - Gutters gap_ = {}; - Dimensions dimensions_{value::ofAuto(), value::ofAuto()}; - Dimensions minDimensions_ = {}; - Dimensions maxDimensions_ = {}; - // Yoga specific properties, not compatible with flexbox specification - FloatOptional aspectRatio_ = {}; - - public: Direction direction() const { - return getEnumData(flags_, directionOffset); + return direction_; } void setDirection(Direction value) { - setEnumData(flags_, directionOffset, value); + direction_ = value; } FlexDirection flexDirection() const { - return getEnumData(flags_, flexdirectionOffset); + return flexDirection_; } void setFlexDirection(FlexDirection value) { - setEnumData(flags_, flexdirectionOffset, value); + flexDirection_ = value; } Justify justifyContent() const { - return getEnumData(flags_, justifyContentOffset); + return justifyContent_; } void setJustifyContent(Justify value) { - setEnumData(flags_, justifyContentOffset, value); + justifyContent_ = value; } Align alignContent() const { - return getEnumData(flags_, alignContentOffset); + return alignContent_; } void setAlignContent(Align value) { - setEnumData(flags_, alignContentOffset, value); + alignContent_ = value; } Align alignItems() const { - return getEnumData(flags_, alignItemsOffset); + return alignItems_; } void setAlignItems(Align value) { - setEnumData(flags_, alignItemsOffset, value); + alignItems_ = value; } Align alignSelf() const { - return getEnumData(flags_, alignSelfOffset); + return alignSelf_; } void setAlignSelf(Align value) { - setEnumData(flags_, alignSelfOffset, value); + alignSelf_ = value; } PositionType positionType() const { - return getEnumData(flags_, positionTypeOffset); + return positionType_; } void setPositionType(PositionType value) { - setEnumData(flags_, positionTypeOffset, value); + positionType_ = value; } Wrap flexWrap() const { - return getEnumData(flags_, flexWrapOffset); + return flexWrap_; } void setFlexWrap(Wrap value) { - setEnumData(flags_, flexWrapOffset, value); + flexWrap_ = value; } Overflow overflow() const { - return getEnumData(flags_, overflowOffset); + return overflow_; } void setOverflow(Overflow value) { - setEnumData(flags_, overflowOffset, value); + overflow_ = value; } Display display() const { - return getEnumData(flags_, displayOffset); + return display_; } void setDisplay(Display value) { - setEnumData(flags_, displayOffset, value); + display_ = value; } FloatOptional flex() const { @@ -282,7 +232,14 @@ class YG_EXPORT Style { } bool operator==(const Style& other) const { - return flags_ == other.flags_ && inexactEquals(flex_, other.flex_) && + return direction_ == other.direction_ && + flexDirection_ == other.flexDirection_ && + justifyContent_ == other.justifyContent_ && + alignContent_ == other.alignContent_ && + alignItems_ == other.alignItems_ && alignSelf_ == other.alignSelf_ && + positionType_ == other.positionType_ && flexWrap_ == other.flexWrap_ && + overflow_ == other.overflow_ && display_ == other.display_ && + inexactEquals(flex_, other.flex_) && inexactEquals(flexGrow_, other.flexGrow_) && inexactEquals(flexShrink_, other.flexShrink_) && inexactEquals(flexBasis_, other.flexBasis_) && @@ -300,6 +257,37 @@ class YG_EXPORT Style { bool operator!=(const Style& other) const { return !(*this == other); } + + private: + using Dimensions = std::array()>; + using Edges = std::array()>; + using Gutters = std::array()>; + + Direction direction_ : bitCount() = Direction::Inherit; + FlexDirection flexDirection_ + : bitCount() = FlexDirection::Column; + Justify justifyContent_ : bitCount() = Justify::FlexStart; + Align alignContent_ : bitCount() = Align::FlexStart; + Align alignItems_ : bitCount() = Align::Stretch; + Align alignSelf_ : bitCount() = Align::Auto; + PositionType positionType_ : bitCount() = PositionType::Static; + Wrap flexWrap_ : bitCount() = Wrap::NoWrap; + Overflow overflow_ : bitCount() = Overflow::Visible; + Display display_ : bitCount() = Display::Flex; + + FloatOptional flex_{}; + FloatOptional flexGrow_{}; + FloatOptional flexShrink_{}; + Style::Length flexBasis_{value::ofAuto()}; + Edges margin_{}; + Edges position_{}; + Edges padding_{}; + Edges border_{}; + Gutters gap_{}; + Dimensions dimensions_{value::ofAuto(), value::ofAuto()}; + Dimensions minDimensions_{}; + Dimensions maxDimensions_{}; + FloatOptional aspectRatio_{}; }; } // namespace facebook::yoga