From 3da82cb09e445448ebd7402b288348f5005b3cf3 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 29 Aug 2023 21:30:37 -0700 Subject: [PATCH] C++ Cleanup 7/N: BitUtils (#1351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: X-link: https://github.com/facebook/react-native/pull/39200 Pull Request resolved: https://github.com/facebook/yoga/pull/1351 ## This diff This splits up `BitUtils.h`, does some minor renaming, and namespace consistency fixes. ## This stack The organization of the C++ internals of Yoga are in need of attention. 1. Some of the C++ internals are namespaced, but others not. 2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these) 2. Most of the files are in a flat hierarchy, except for event tracing in its own folder 3. Some files and functions begin with YG, others don’t 4. Some functions are uppercase, others are not 5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about 6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h) 7. There is no clear indication from file structure or type naming what is private vs not 8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers This stack does some much needed spring cleaning: 1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy 3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended 4. Utils files are split 5. Most C++ internals drop the YG prefix 6. Most C++ internal function names are all lower camel case 7. We start to split up Yoga.cpp 8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings 9. It is not possible to use private APIs without static casting handles to internal classes This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well. These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer. Reviewed By: rshest Differential Revision: D48768374 fbshipit-source-id: 0e69baf750fec353b2e205afabae9d2501e85be2 --- tests/BitUtilsTest.cpp | 204 -------------------- tests/NumericBitfieldTest.cpp | 204 ++++++++++++++++++++ yoga/bits/EnumBitset.h | 19 ++ yoga/{BitUtils.h => bits/NumericBitfield.h} | 29 +-- yoga/config/Config.cpp | 2 +- yoga/config/Config.h | 8 +- yoga/node/LayoutResults.h | 17 +- yoga/style/Style.h | 57 +++--- 8 files changed, 272 insertions(+), 268 deletions(-) delete mode 100644 tests/BitUtilsTest.cpp create mode 100644 tests/NumericBitfieldTest.cpp create mode 100644 yoga/bits/EnumBitset.h rename yoga/{BitUtils.h => bits/NumericBitfield.h} (64%) diff --git a/tests/BitUtilsTest.cpp b/tests/BitUtilsTest.cpp deleted file mode 100644 index 211a155ca9..0000000000 --- a/tests/BitUtilsTest.cpp +++ /dev/null @@ -1,204 +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(BitUtils, one_boolean_defaults_to_false) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - static_assert( - detail::getBooleanData(flags, 0) == false, - "first boolean member must default to false"); -} - -TEST(BitUtils, one_boolean_can_be_initialized_to_true) { - constexpr uint8_t flags = 1; - - ASSERT_EQ(detail::getBooleanData(flags, 0), true); - static_assert( - detail::getBooleanData(flags, 0) == true, - "first boolean member must be initialized to true"); -} - -TEST(BitUtils, one_boolean_can_be_set_to_true) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 0, true); - ASSERT_EQ(detail::getBooleanData(flags, 0), true); -} - -TEST(BitUtils, second_boolean_defaults_to_false) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getBooleanData(flags, 1), false); - static_assert( - detail::getBooleanData(flags, 1) == false, - "second boolean member must default to false"); -} - -TEST(BitUtils, second_boolean_can_be_initialized_to_true) { - constexpr uint8_t flags = 2; - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), true); - static_assert( - detail::getBooleanData(flags, 0) == false, - "first boolean member must default to false"); - static_assert( - detail::getBooleanData(flags, 1) == true, - "second boolean member must be initialized to true"); -} - -TEST(BitUtils, second_boolean_can_be_set_to_true) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 1, true); - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), true); -} - -TEST(BitUtils, third_boolean_defaults_to_false) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getBooleanData(flags, 2), false); - static_assert( - detail::getBooleanData(flags, 2) == false, - "second boolean member must default to false"); -} - -TEST(BitUtils, third_boolean_can_be_initialized_to_true) { - constexpr uint8_t flags = 4; - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), false); - ASSERT_EQ(detail::getBooleanData(flags, 2), true); - static_assert( - detail::getBooleanData(flags, 0) == false, - "first boolean member must default to false"); - static_assert( - detail::getBooleanData(flags, 1) == false, - "second boolean member must default to false"); - static_assert( - detail::getBooleanData(flags, 2) == true, - "second boolean member must be initialized to true"); -} - -TEST(BitUtils, third_boolean_can_be_set_to_true) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 2, true); - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), false); - ASSERT_EQ(detail::getBooleanData(flags, 2), true); -} - -TEST(BitUtils, setting_boolean_values_does_not_spill_over) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 1, (bool) 7); - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), true); - ASSERT_EQ(detail::getBooleanData(flags, 2), false); -} - -TEST(BitUtils, first_enum_defaults_to_0) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getEnumData(flags, 0), YGAlignAuto); - static_assert( - detail::getEnumData(flags, 0) == YGAlignAuto, - "first enum member must default to 0"); -} - -TEST(BitUtils, first_enum_can_be_set) { - uint8_t flags = 0; - - detail::setEnumData(flags, 0, YGAlignSpaceBetween); - - ASSERT_EQ(detail::getEnumData(flags, 0), YGAlignSpaceBetween); -} - -TEST(BitUtils, second_enum_defaults_to_0) { - constexpr uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgeOffset = 3; - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getEnumData(flags, edgeOffset), YGEdgeLeft); - static_assert( - detail::getEnumData(flags, alignOffset) == YGAlignAuto, - "first enum member must default to 0"); - static_assert( - detail::getEnumData(flags, edgeOffset) == YGEdgeLeft, - "second enum member must default to 0"); -} - -TEST(BitUtils, second_enum_can_be_set) { - uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgeOffset = 3; - - detail::setEnumData(flags, edgeOffset, YGEdgeAll); - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getEnumData(flags, edgeOffset), YGEdgeAll); -} - -TEST(BitUtils, third_enum_defaults_to_0) { - constexpr uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t boolOffset = 3; - static constexpr size_t edgesOffset = 4; - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); - ASSERT_EQ(detail::getEnumData(flags, edgesOffset), YGEdgeLeft); - static_assert( - detail::getEnumData(flags, alignOffset) == YGAlignAuto, - "first enum member must default to 0"); - static_assert( - detail::getBooleanData(flags, boolOffset) == false, - "middle boolean member must default to false"); - static_assert( - detail::getEnumData(flags, edgesOffset) == YGEdgeLeft, - "last enum member must default to 0"); -} - -TEST(BitUtils, third_enum_can_be_set) { - uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t boolOffset = 3; - static constexpr size_t edgesOffset = 4; - - detail::setEnumData(flags, edgesOffset, YGEdgeVertical); - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); - ASSERT_EQ(detail::getEnumData(flags, edgesOffset), YGEdgeVertical); -} - -TEST(BitUtils, setting_values_does_not_spill_over) { - uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgesOffset = 3; - static constexpr size_t boolOffset = 7; - - detail::setEnumData(flags, edgesOffset, (YGEdge) 0xffffff); - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), 0); - ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); - ASSERT_EQ(detail::getEnumData(flags, edgesOffset), 0xf); -} - -} // namespace facebook::yoga diff --git a/tests/NumericBitfieldTest.cpp b/tests/NumericBitfieldTest.cpp new file mode 100644 index 0000000000..9b487cee21 --- /dev/null +++ b/tests/NumericBitfieldTest.cpp @@ -0,0 +1,204 @@ +/* + * 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 uint8_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 uint8_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) { + uint8_t flags = 0; + + setBooleanData(flags, 0, true); + ASSERT_EQ(getBooleanData(flags, 0), true); +} + +TEST(NumericBitfield, second_boolean_defaults_to_false) { + constexpr uint8_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 uint8_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) { + uint8_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 uint8_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 uint8_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) { + uint8_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) { + uint8_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 uint8_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) { + uint8_t flags = 0; + + setEnumData(flags, 0, YGAlignSpaceBetween); + + ASSERT_EQ(getEnumData(flags, 0), YGAlignSpaceBetween); +} + +TEST(NumericBitfield, second_enum_defaults_to_0) { + constexpr uint8_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) { + uint8_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 uint8_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) { + uint8_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) { + uint8_t flags = 0; + static constexpr size_t alignOffset = 0; + static constexpr size_t edgesOffset = 3; + static constexpr size_t boolOffset = 7; + + setEnumData(flags, edgesOffset, (YGEdge) 0xffffff); + + 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/bits/EnumBitset.h b/yoga/bits/EnumBitset.h new file mode 100644 index 0000000000..3dff663f8f --- /dev/null +++ b/yoga/bits/EnumBitset.h @@ -0,0 +1,19 @@ +/* + * 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 + +namespace facebook::yoga { + +// std::bitset with one bit for each option defined in YG_ENUM_SEQ_DECL +template +using EnumBitset = std::bitset()>; + +} // namespace facebook::yoga diff --git a/yoga/BitUtils.h b/yoga/bits/NumericBitfield.h similarity index 64% rename from yoga/BitUtils.h rename to yoga/bits/NumericBitfield.h index 7c91550585..af3fc6927d 100644 --- a/yoga/BitUtils.h +++ b/yoga/bits/NumericBitfield.h @@ -13,11 +13,7 @@ #include -namespace facebook::yoga::detail { - -// std::bitset with one bit for each option defined in YG_ENUM_SEQ_DECL -template -using EnumBitset = std::bitset()>; +namespace facebook::yoga::details { constexpr size_t log2ceilFn(size_t n) { return n < 1 ? 0 : (1 + log2ceilFn(n / 2)); @@ -27,30 +23,37 @@ constexpr int mask(size_t bitWidth, size_t index) { return ((1 << bitWidth) - 1) << index; } +} // namespace facebook::yoga::details + +namespace facebook::yoga { + // The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL template -constexpr size_t bitWidthFn() { +constexpr size_t minimumBitCount() { static_assert( enums::count() > 0, "Enums must have at least one entries"); - return log2ceilFn(enums::count() - 1); + return details::log2ceilFn(enums::count() - 1); } template constexpr Enum getEnumData(int flags, size_t index) { - return static_cast((flags & mask(bitWidthFn(), index)) >> index); + return static_cast( + (flags & details::mask(minimumBitCount(), index)) >> index); } template void setEnumData(uint32_t& flags, size_t index, int newValue) { - flags = (flags & ~mask(bitWidthFn(), index)) | - ((newValue << index) & (mask(bitWidthFn(), index))); + flags = (flags & ~details::mask(minimumBitCount(), index)) | + ((newValue << index) & (details::mask(minimumBitCount(), index))); } template void setEnumData(uint8_t& flags, size_t index, int newValue) { - flags = (flags & ~static_cast(mask(bitWidthFn(), index))) | + flags = + (flags & + ~static_cast(details::mask(minimumBitCount(), index))) | ((newValue << index) & - (static_cast(mask(bitWidthFn(), index)))); + (static_cast(details::mask(minimumBitCount(), index)))); } constexpr bool getBooleanData(int flags, size_t index) { @@ -65,4 +68,4 @@ inline void setBooleanData(uint8_t& flags, size_t index, bool value) { } } -} // namespace facebook::yoga::detail +} // namespace facebook::yoga diff --git a/yoga/config/Config.cpp b/yoga/config/Config.cpp index 2f07454b97..d8809cf5a2 100644 --- a/yoga/config/Config.cpp +++ b/yoga/config/Config.cpp @@ -46,7 +46,7 @@ bool Config::isExperimentalFeatureEnabled(YGExperimentalFeature feature) const { return experimentalFeatures_.test(feature); } -ExperimentalFeatureSet Config::getEnabledExperiments() const { +EnumBitset Config::getEnabledExperiments() const { return experimentalFeatures_; } diff --git a/yoga/config/Config.h b/yoga/config/Config.h index 6470ebde4d..d0894b86be 100644 --- a/yoga/config/Config.h +++ b/yoga/config/Config.h @@ -9,7 +9,7 @@ #include -#include +#include #include // Tag struct used to form the opaque YGConfigRef for the public C API @@ -38,8 +38,6 @@ using CloneWithContextFn = YGNodeRef (*)( int childIndex, void* cloneContext); -using ExperimentalFeatureSet = detail::EnumBitset; - #pragma pack(push) #pragma pack(1) // Packed structure of <32-bit options to miminize size per node. @@ -65,7 +63,7 @@ class YOGA_EXPORT Config : public ::YGConfig { YGExperimentalFeature feature, bool enabled); bool isExperimentalFeatureEnabled(YGExperimentalFeature feature) const; - ExperimentalFeatureSet getEnabledExperiments() const; + EnumBitset getEnabledExperiments() const; void setErrata(YGErrata errata); void addErrata(YGErrata errata); @@ -104,7 +102,7 @@ class YOGA_EXPORT Config : public ::YGConfig { } logger_; ConfigFlags flags_{}; - ExperimentalFeatureSet experimentalFeatures_{}; + EnumBitset experimentalFeatures_{}; YGErrata errata_ = YGErrataNone; float pointScaleFactor_ = 1.0f; void* context_ = nullptr; diff --git a/yoga/node/LayoutResults.h b/yoga/node/LayoutResults.h index d920e9a24c..c0d2bee26d 100644 --- a/yoga/node/LayoutResults.h +++ b/yoga/node/LayoutResults.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include @@ -23,7 +23,7 @@ struct LayoutResults { private: static constexpr size_t directionOffset = 0; static constexpr size_t hadOverflowOffset = - directionOffset + facebook::yoga::detail::bitWidthFn(); + directionOffset + minimumBitCount(); uint8_t flags = 0; public: @@ -43,21 +43,16 @@ struct LayoutResults { YGCachedMeasurement cachedLayout = YGCachedMeasurement(); YGDirection direction() const { - return facebook::yoga::detail::getEnumData( - flags, directionOffset); + return getEnumData(flags, directionOffset); } void setDirection(YGDirection direction) { - facebook::yoga::detail::setEnumData( - flags, directionOffset, direction); + setEnumData(flags, directionOffset, direction); } - bool hadOverflow() const { - return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset); - } + bool hadOverflow() const { return getBooleanData(flags, hadOverflowOffset); } void setHadOverflow(bool hadOverflow) { - facebook::yoga::detail::setBooleanData( - flags, hadOverflowOffset, hadOverflow); + setBooleanData(flags, hadOverflowOffset, hadOverflow); } bool operator==(LayoutResults layout) const; diff --git a/yoga/style/Style.h b/yoga/style/Style.h index 49bb8ece67..10854fd6fb 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -14,8 +14,8 @@ #include #include -#include +#include #include #include @@ -34,11 +34,9 @@ class YOGA_EXPORT Style { struct BitfieldRef { Style& style; size_t offset; - operator T() const { - return facebook::yoga::detail::getEnumData(style.flags, offset); - } + operator T() const { return getEnumData(style.flags, offset); } BitfieldRef& operator=(T x) { - facebook::yoga::detail::setEnumData(style.flags, offset, x); + setEnumData(style.flags, offset, x); return *this; } }; @@ -85,23 +83,23 @@ class YOGA_EXPORT Style { private: static constexpr size_t directionOffset = 0; static constexpr size_t flexdirectionOffset = - directionOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t justifyContentOffset = flexdirectionOffset + - facebook::yoga::detail::bitWidthFn(); + directionOffset + minimumBitCount(); + static constexpr size_t justifyContentOffset = + flexdirectionOffset + minimumBitCount(); static constexpr size_t alignContentOffset = - justifyContentOffset + facebook::yoga::detail::bitWidthFn(); + justifyContentOffset + minimumBitCount(); static constexpr size_t alignItemsOffset = - alignContentOffset + facebook::yoga::detail::bitWidthFn(); + alignContentOffset + minimumBitCount(); static constexpr size_t alignSelfOffset = - alignItemsOffset + facebook::yoga::detail::bitWidthFn(); + alignItemsOffset + minimumBitCount(); static constexpr size_t positionTypeOffset = - alignSelfOffset + facebook::yoga::detail::bitWidthFn(); + alignSelfOffset + minimumBitCount(); static constexpr size_t flexWrapOffset = - positionTypeOffset + facebook::yoga::detail::bitWidthFn(); + positionTypeOffset + minimumBitCount(); static constexpr size_t overflowOffset = - flexWrapOffset + facebook::yoga::detail::bitWidthFn(); + flexWrapOffset + minimumBitCount(); static constexpr size_t displayOffset = - overflowOffset + facebook::yoga::detail::bitWidthFn(); + overflowOffset + minimumBitCount(); uint32_t flags = 0; @@ -125,65 +123,56 @@ class YOGA_EXPORT Style { using ValueRepr = std::remove_reference::type; YGDirection direction() const { - return facebook::yoga::detail::getEnumData( - flags, directionOffset); + return getEnumData(flags, directionOffset); } BitfieldRef direction() { return {*this, directionOffset}; } YGFlexDirection flexDirection() const { - return facebook::yoga::detail::getEnumData( - flags, flexdirectionOffset); + return getEnumData(flags, flexdirectionOffset); } BitfieldRef flexDirection() { return {*this, flexdirectionOffset}; } YGJustify justifyContent() const { - return facebook::yoga::detail::getEnumData( - flags, justifyContentOffset); + return getEnumData(flags, justifyContentOffset); } BitfieldRef justifyContent() { return {*this, justifyContentOffset}; } YGAlign alignContent() const { - return facebook::yoga::detail::getEnumData( - flags, alignContentOffset); + return getEnumData(flags, alignContentOffset); } BitfieldRef alignContent() { return {*this, alignContentOffset}; } YGAlign alignItems() const { - return facebook::yoga::detail::getEnumData( - flags, alignItemsOffset); + return getEnumData(flags, alignItemsOffset); } BitfieldRef alignItems() { return {*this, alignItemsOffset}; } YGAlign alignSelf() const { - return facebook::yoga::detail::getEnumData(flags, alignSelfOffset); + return getEnumData(flags, alignSelfOffset); } BitfieldRef alignSelf() { return {*this, alignSelfOffset}; } YGPositionType positionType() const { - return facebook::yoga::detail::getEnumData( - flags, positionTypeOffset); + return getEnumData(flags, positionTypeOffset); } BitfieldRef positionType() { return {*this, positionTypeOffset}; } - YGWrap flexWrap() const { - return facebook::yoga::detail::getEnumData(flags, flexWrapOffset); - } + YGWrap flexWrap() const { return getEnumData(flags, flexWrapOffset); } BitfieldRef flexWrap() { return {*this, flexWrapOffset}; } YGOverflow overflow() const { - return facebook::yoga::detail::getEnumData( - flags, overflowOffset); + return getEnumData(flags, overflowOffset); } BitfieldRef overflow() { return {*this, overflowOffset}; } YGDisplay display() const { - return facebook::yoga::detail::getEnumData(flags, displayOffset); + return getEnumData(flags, displayOffset); } BitfieldRef display() { return {*this, displayOffset}; }