Revert D48768374: C++ Cleanup 7/N: BitUtils
Differential Revision: D48768374 Original commit changeset: 921a22ec88bd Original Phabricator Diff: D48768374 fbshipit-source-id: 59106ab3d03619940023dac1c2af62fd88566773
This commit is contained in:
committed by
Facebook GitHub Bot
parent
866b4f7d62
commit
8a95b785a8
204
tests/BitUtilsTest.cpp
Normal file
204
tests/BitUtilsTest.cpp
Normal file
@@ -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 <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <yoga/BitUtils.h>
|
||||||
|
|
||||||
|
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<YGAlign>(flags, 0), YGAlignAuto);
|
||||||
|
static_assert(
|
||||||
|
detail::getEnumData<YGAlign>(flags, 0) == YGAlignAuto,
|
||||||
|
"first enum member must default to 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BitUtils, first_enum_can_be_set) {
|
||||||
|
uint8_t flags = 0;
|
||||||
|
|
||||||
|
detail::setEnumData<YGAlign>(flags, 0, YGAlignSpaceBetween);
|
||||||
|
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGAlign>(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<YGAlign>(flags, alignOffset), YGAlignAuto);
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGEdge>(flags, edgeOffset), YGEdgeLeft);
|
||||||
|
static_assert(
|
||||||
|
detail::getEnumData<YGAlign>(flags, alignOffset) == YGAlignAuto,
|
||||||
|
"first enum member must default to 0");
|
||||||
|
static_assert(
|
||||||
|
detail::getEnumData<YGEdge>(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<YGEdge>(flags, edgeOffset, YGEdgeAll);
|
||||||
|
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGAlign>(flags, alignOffset), YGAlignAuto);
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGEdge>(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<YGAlign>(flags, alignOffset), YGAlignAuto);
|
||||||
|
ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false);
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGEdge>(flags, edgesOffset), YGEdgeLeft);
|
||||||
|
static_assert(
|
||||||
|
detail::getEnumData<YGAlign>(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<YGEdge>(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<YGEdge>(flags, edgesOffset, YGEdgeVertical);
|
||||||
|
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGAlign>(flags, alignOffset), YGAlignAuto);
|
||||||
|
ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false);
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGEdge>(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<YGEdge>(flags, edgesOffset, (YGEdge) 0xffffff);
|
||||||
|
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGAlign>(flags, alignOffset), 0);
|
||||||
|
ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false);
|
||||||
|
ASSERT_EQ(detail::getEnumData<YGEdge>(flags, edgesOffset), 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace facebook::yoga
|
@@ -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 <gtest/gtest.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <yoga/bits/NumericBitfield.h>
|
|
||||||
|
|
||||||
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<YGAlign>(flags, 0), YGAlignAuto);
|
|
||||||
static_assert(
|
|
||||||
getEnumData<YGAlign>(flags, 0) == YGAlignAuto,
|
|
||||||
"first enum member must default to 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(NumericBitfield, first_enum_can_be_set) {
|
|
||||||
uint8_t flags = 0;
|
|
||||||
|
|
||||||
setEnumData<YGAlign>(flags, 0, YGAlignSpaceBetween);
|
|
||||||
|
|
||||||
ASSERT_EQ(getEnumData<YGAlign>(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<YGAlign>(flags, alignOffset), YGAlignAuto);
|
|
||||||
ASSERT_EQ(getEnumData<YGEdge>(flags, edgeOffset), YGEdgeLeft);
|
|
||||||
static_assert(
|
|
||||||
getEnumData<YGAlign>(flags, alignOffset) == YGAlignAuto,
|
|
||||||
"first enum member must default to 0");
|
|
||||||
static_assert(
|
|
||||||
getEnumData<YGEdge>(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<YGEdge>(flags, edgeOffset, YGEdgeAll);
|
|
||||||
|
|
||||||
ASSERT_EQ(getEnumData<YGAlign>(flags, alignOffset), YGAlignAuto);
|
|
||||||
ASSERT_EQ(getEnumData<YGEdge>(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<YGAlign>(flags, alignOffset), YGAlignAuto);
|
|
||||||
ASSERT_EQ(getBooleanData(flags, boolOffset), false);
|
|
||||||
ASSERT_EQ(getEnumData<YGEdge>(flags, edgesOffset), YGEdgeLeft);
|
|
||||||
static_assert(
|
|
||||||
getEnumData<YGAlign>(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<YGEdge>(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<YGEdge>(flags, edgesOffset, YGEdgeVertical);
|
|
||||||
|
|
||||||
ASSERT_EQ(getEnumData<YGAlign>(flags, alignOffset), YGAlignAuto);
|
|
||||||
ASSERT_EQ(getBooleanData(flags, boolOffset), false);
|
|
||||||
ASSERT_EQ(getEnumData<YGEdge>(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<YGEdge>(flags, edgesOffset, (YGEdge) 0xffffff);
|
|
||||||
|
|
||||||
ASSERT_EQ(getEnumData<YGAlign>(flags, alignOffset), 0);
|
|
||||||
ASSERT_EQ(getBooleanData(flags, boolOffset), false);
|
|
||||||
ASSERT_EQ(getEnumData<YGEdge>(flags, edgesOffset), 0xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace facebook::yoga
|
|
@@ -13,7 +13,11 @@
|
|||||||
|
|
||||||
#include <yoga/YGEnums.h>
|
#include <yoga/YGEnums.h>
|
||||||
|
|
||||||
namespace facebook::yoga::details {
|
namespace facebook::yoga::detail {
|
||||||
|
|
||||||
|
// std::bitset with one bit for each option defined in YG_ENUM_SEQ_DECL
|
||||||
|
template <typename Enum>
|
||||||
|
using EnumBitset = std::bitset<facebook::yoga::enums::count<Enum>()>;
|
||||||
|
|
||||||
constexpr size_t log2ceilFn(size_t n) {
|
constexpr size_t log2ceilFn(size_t n) {
|
||||||
return n < 1 ? 0 : (1 + log2ceilFn(n / 2));
|
return n < 1 ? 0 : (1 + log2ceilFn(n / 2));
|
||||||
@@ -23,37 +27,30 @@ constexpr int mask(size_t bitWidth, size_t index) {
|
|||||||
return ((1 << bitWidth) - 1) << 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
|
// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
constexpr size_t minimumBitCount() {
|
constexpr size_t bitWidthFn() {
|
||||||
static_assert(
|
static_assert(
|
||||||
enums::count<Enum>() > 0, "Enums must have at least one entries");
|
enums::count<Enum>() > 0, "Enums must have at least one entries");
|
||||||
return details::log2ceilFn(enums::count<Enum>() - 1);
|
return log2ceilFn(enums::count<Enum>() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
constexpr Enum getEnumData(int flags, size_t index) {
|
constexpr Enum getEnumData(int flags, size_t index) {
|
||||||
return static_cast<Enum>(
|
return static_cast<Enum>((flags & mask(bitWidthFn<Enum>(), index)) >> index);
|
||||||
(flags & details::mask(minimumBitCount<Enum>(), index)) >> index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
void setEnumData(uint32_t& flags, size_t index, int newValue) {
|
void setEnumData(uint32_t& flags, size_t index, int newValue) {
|
||||||
flags = (flags & ~details::mask(minimumBitCount<Enum>(), index)) |
|
flags = (flags & ~mask(bitWidthFn<Enum>(), index)) |
|
||||||
((newValue << index) & (details::mask(minimumBitCount<Enum>(), index)));
|
((newValue << index) & (mask(bitWidthFn<Enum>(), index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
void setEnumData(uint8_t& flags, size_t index, int newValue) {
|
void setEnumData(uint8_t& flags, size_t index, int newValue) {
|
||||||
flags =
|
flags = (flags & ~static_cast<uint8_t>(mask(bitWidthFn<Enum>(), index))) |
|
||||||
(flags &
|
|
||||||
~static_cast<uint8_t>(details::mask(minimumBitCount<Enum>(), index))) |
|
|
||||||
((newValue << index) &
|
((newValue << index) &
|
||||||
(static_cast<uint8_t>(details::mask(minimumBitCount<Enum>(), index))));
|
(static_cast<uint8_t>(mask(bitWidthFn<Enum>(), index))));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool getBooleanData(int flags, size_t index) {
|
constexpr bool getBooleanData(int flags, size_t index) {
|
||||||
@@ -68,4 +65,4 @@ inline void setBooleanData(uint8_t& flags, size_t index, bool value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace facebook::yoga
|
} // namespace facebook::yoga::detail
|
@@ -1,19 +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 <bitset>
|
|
||||||
#include <yoga/YGEnums.h>
|
|
||||||
|
|
||||||
namespace facebook::yoga {
|
|
||||||
|
|
||||||
// std::bitset with one bit for each option defined in YG_ENUM_SEQ_DECL
|
|
||||||
template <typename Enum>
|
|
||||||
using EnumBitset = std::bitset<enums::count<Enum>()>;
|
|
||||||
|
|
||||||
} // namespace facebook::yoga
|
|
@@ -46,7 +46,7 @@ bool Config::isExperimentalFeatureEnabled(YGExperimentalFeature feature) const {
|
|||||||
return experimentalFeatures_.test(feature);
|
return experimentalFeatures_.test(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumBitset<YGExperimentalFeature> Config::getEnabledExperiments() const {
|
ExperimentalFeatureSet Config::getEnabledExperiments() const {
|
||||||
return experimentalFeatures_;
|
return experimentalFeatures_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
|
|
||||||
#include <yoga/bits/EnumBitset.h>
|
#include <yoga/BitUtils.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
#include <yoga/Yoga-internal.h>
|
||||||
|
|
||||||
// Tag struct used to form the opaque YGConfigRef for the public C API
|
// Tag struct used to form the opaque YGConfigRef for the public C API
|
||||||
@@ -38,6 +38,8 @@ using CloneWithContextFn = YGNodeRef (*)(
|
|||||||
int childIndex,
|
int childIndex,
|
||||||
void* cloneContext);
|
void* cloneContext);
|
||||||
|
|
||||||
|
using ExperimentalFeatureSet = detail::EnumBitset<YGExperimentalFeature>;
|
||||||
|
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
// Packed structure of <32-bit options to miminize size per node.
|
// Packed structure of <32-bit options to miminize size per node.
|
||||||
@@ -63,7 +65,7 @@ public:
|
|||||||
YGExperimentalFeature feature,
|
YGExperimentalFeature feature,
|
||||||
bool enabled);
|
bool enabled);
|
||||||
bool isExperimentalFeatureEnabled(YGExperimentalFeature feature) const;
|
bool isExperimentalFeatureEnabled(YGExperimentalFeature feature) const;
|
||||||
EnumBitset<YGExperimentalFeature> getEnabledExperiments() const;
|
ExperimentalFeatureSet getEnabledExperiments() const;
|
||||||
|
|
||||||
void setErrata(YGErrata errata);
|
void setErrata(YGErrata errata);
|
||||||
void addErrata(YGErrata errata);
|
void addErrata(YGErrata errata);
|
||||||
@@ -102,7 +104,7 @@ private:
|
|||||||
} logger_;
|
} logger_;
|
||||||
|
|
||||||
ConfigFlags flags_{};
|
ConfigFlags flags_{};
|
||||||
EnumBitset<YGExperimentalFeature> experimentalFeatures_{};
|
ExperimentalFeatureSet experimentalFeatures_{};
|
||||||
YGErrata errata_ = YGErrataNone;
|
YGErrata errata_ = YGErrataNone;
|
||||||
float pointScaleFactor_ = 1.0f;
|
float pointScaleFactor_ = 1.0f;
|
||||||
void* context_ = nullptr;
|
void* context_ = nullptr;
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <yoga/bits/NumericBitfield.h>
|
#include <yoga/BitUtils.h>
|
||||||
#include <yoga/numeric/FloatOptional.h>
|
#include <yoga/numeric/FloatOptional.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
#include <yoga/Yoga-internal.h>
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ struct LayoutResults {
|
|||||||
private:
|
private:
|
||||||
static constexpr size_t directionOffset = 0;
|
static constexpr size_t directionOffset = 0;
|
||||||
static constexpr size_t hadOverflowOffset =
|
static constexpr size_t hadOverflowOffset =
|
||||||
directionOffset + minimumBitCount<YGDirection>();
|
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -43,16 +43,21 @@ public:
|
|||||||
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
|
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
|
||||||
|
|
||||||
YGDirection direction() const {
|
YGDirection direction() const {
|
||||||
return getEnumData<YGDirection>(flags, directionOffset);
|
return facebook::yoga::detail::getEnumData<YGDirection>(
|
||||||
|
flags, directionOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDirection(YGDirection direction) {
|
void setDirection(YGDirection direction) {
|
||||||
setEnumData<YGDirection>(flags, directionOffset, direction);
|
facebook::yoga::detail::setEnumData<YGDirection>(
|
||||||
|
flags, directionOffset, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hadOverflow() const { return getBooleanData(flags, hadOverflowOffset); }
|
bool hadOverflow() const {
|
||||||
|
return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset);
|
||||||
|
}
|
||||||
void setHadOverflow(bool hadOverflow) {
|
void setHadOverflow(bool hadOverflow) {
|
||||||
setBooleanData(flags, hadOverflowOffset, hadOverflow);
|
facebook::yoga::detail::setBooleanData(
|
||||||
|
flags, hadOverflowOffset, hadOverflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(LayoutResults layout) const;
|
bool operator==(LayoutResults layout) const;
|
||||||
|
@@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
#include <yoga/Yoga-internal.h>
|
||||||
|
#include <yoga/BitUtils.h>
|
||||||
|
|
||||||
#include <yoga/bits/NumericBitfield.h>
|
|
||||||
#include <yoga/numeric/FloatOptional.h>
|
#include <yoga/numeric/FloatOptional.h>
|
||||||
#include <yoga/style/CompactValue.h>
|
#include <yoga/style/CompactValue.h>
|
||||||
|
|
||||||
@@ -34,9 +34,11 @@ public:
|
|||||||
struct BitfieldRef {
|
struct BitfieldRef {
|
||||||
Style& style;
|
Style& style;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
operator T() const { return getEnumData<T>(style.flags, offset); }
|
operator T() const {
|
||||||
|
return facebook::yoga::detail::getEnumData<T>(style.flags, offset);
|
||||||
|
}
|
||||||
BitfieldRef<T>& operator=(T x) {
|
BitfieldRef<T>& operator=(T x) {
|
||||||
setEnumData<T>(style.flags, offset, x);
|
facebook::yoga::detail::setEnumData<T>(style.flags, offset, x);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -83,23 +85,23 @@ public:
|
|||||||
private:
|
private:
|
||||||
static constexpr size_t directionOffset = 0;
|
static constexpr size_t directionOffset = 0;
|
||||||
static constexpr size_t flexdirectionOffset =
|
static constexpr size_t flexdirectionOffset =
|
||||||
directionOffset + minimumBitCount<YGDirection>();
|
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
|
||||||
static constexpr size_t justifyContentOffset =
|
static constexpr size_t justifyContentOffset = flexdirectionOffset +
|
||||||
flexdirectionOffset + minimumBitCount<YGFlexDirection>();
|
facebook::yoga::detail::bitWidthFn<YGFlexDirection>();
|
||||||
static constexpr size_t alignContentOffset =
|
static constexpr size_t alignContentOffset =
|
||||||
justifyContentOffset + minimumBitCount<YGJustify>();
|
justifyContentOffset + facebook::yoga::detail::bitWidthFn<YGJustify>();
|
||||||
static constexpr size_t alignItemsOffset =
|
static constexpr size_t alignItemsOffset =
|
||||||
alignContentOffset + minimumBitCount<YGAlign>();
|
alignContentOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
|
||||||
static constexpr size_t alignSelfOffset =
|
static constexpr size_t alignSelfOffset =
|
||||||
alignItemsOffset + minimumBitCount<YGAlign>();
|
alignItemsOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
|
||||||
static constexpr size_t positionTypeOffset =
|
static constexpr size_t positionTypeOffset =
|
||||||
alignSelfOffset + minimumBitCount<YGAlign>();
|
alignSelfOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
|
||||||
static constexpr size_t flexWrapOffset =
|
static constexpr size_t flexWrapOffset =
|
||||||
positionTypeOffset + minimumBitCount<YGPositionType>();
|
positionTypeOffset + facebook::yoga::detail::bitWidthFn<YGPositionType>();
|
||||||
static constexpr size_t overflowOffset =
|
static constexpr size_t overflowOffset =
|
||||||
flexWrapOffset + minimumBitCount<YGWrap>();
|
flexWrapOffset + facebook::yoga::detail::bitWidthFn<YGWrap>();
|
||||||
static constexpr size_t displayOffset =
|
static constexpr size_t displayOffset =
|
||||||
overflowOffset + minimumBitCount<YGOverflow>();
|
overflowOffset + facebook::yoga::detail::bitWidthFn<YGOverflow>();
|
||||||
|
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
|
|
||||||
@@ -123,56 +125,65 @@ public:
|
|||||||
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
|
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
|
||||||
|
|
||||||
YGDirection direction() const {
|
YGDirection direction() const {
|
||||||
return getEnumData<YGDirection>(flags, directionOffset);
|
return facebook::yoga::detail::getEnumData<YGDirection>(
|
||||||
|
flags, directionOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGDirection> direction() { return {*this, directionOffset}; }
|
BitfieldRef<YGDirection> direction() { return {*this, directionOffset}; }
|
||||||
|
|
||||||
YGFlexDirection flexDirection() const {
|
YGFlexDirection flexDirection() const {
|
||||||
return getEnumData<YGFlexDirection>(flags, flexdirectionOffset);
|
return facebook::yoga::detail::getEnumData<YGFlexDirection>(
|
||||||
|
flags, flexdirectionOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGFlexDirection> flexDirection() {
|
BitfieldRef<YGFlexDirection> flexDirection() {
|
||||||
return {*this, flexdirectionOffset};
|
return {*this, flexdirectionOffset};
|
||||||
}
|
}
|
||||||
|
|
||||||
YGJustify justifyContent() const {
|
YGJustify justifyContent() const {
|
||||||
return getEnumData<YGJustify>(flags, justifyContentOffset);
|
return facebook::yoga::detail::getEnumData<YGJustify>(
|
||||||
|
flags, justifyContentOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGJustify> justifyContent() {
|
BitfieldRef<YGJustify> justifyContent() {
|
||||||
return {*this, justifyContentOffset};
|
return {*this, justifyContentOffset};
|
||||||
}
|
}
|
||||||
|
|
||||||
YGAlign alignContent() const {
|
YGAlign alignContent() const {
|
||||||
return getEnumData<YGAlign>(flags, alignContentOffset);
|
return facebook::yoga::detail::getEnumData<YGAlign>(
|
||||||
|
flags, alignContentOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGAlign> alignContent() { return {*this, alignContentOffset}; }
|
BitfieldRef<YGAlign> alignContent() { return {*this, alignContentOffset}; }
|
||||||
|
|
||||||
YGAlign alignItems() const {
|
YGAlign alignItems() const {
|
||||||
return getEnumData<YGAlign>(flags, alignItemsOffset);
|
return facebook::yoga::detail::getEnumData<YGAlign>(
|
||||||
|
flags, alignItemsOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGAlign> alignItems() { return {*this, alignItemsOffset}; }
|
BitfieldRef<YGAlign> alignItems() { return {*this, alignItemsOffset}; }
|
||||||
|
|
||||||
YGAlign alignSelf() const {
|
YGAlign alignSelf() const {
|
||||||
return getEnumData<YGAlign>(flags, alignSelfOffset);
|
return facebook::yoga::detail::getEnumData<YGAlign>(flags, alignSelfOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGAlign> alignSelf() { return {*this, alignSelfOffset}; }
|
BitfieldRef<YGAlign> alignSelf() { return {*this, alignSelfOffset}; }
|
||||||
|
|
||||||
YGPositionType positionType() const {
|
YGPositionType positionType() const {
|
||||||
return getEnumData<YGPositionType>(flags, positionTypeOffset);
|
return facebook::yoga::detail::getEnumData<YGPositionType>(
|
||||||
|
flags, positionTypeOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGPositionType> positionType() {
|
BitfieldRef<YGPositionType> positionType() {
|
||||||
return {*this, positionTypeOffset};
|
return {*this, positionTypeOffset};
|
||||||
}
|
}
|
||||||
|
|
||||||
YGWrap flexWrap() const { return getEnumData<YGWrap>(flags, flexWrapOffset); }
|
YGWrap flexWrap() const {
|
||||||
|
return facebook::yoga::detail::getEnumData<YGWrap>(flags, flexWrapOffset);
|
||||||
|
}
|
||||||
BitfieldRef<YGWrap> flexWrap() { return {*this, flexWrapOffset}; }
|
BitfieldRef<YGWrap> flexWrap() { return {*this, flexWrapOffset}; }
|
||||||
|
|
||||||
YGOverflow overflow() const {
|
YGOverflow overflow() const {
|
||||||
return getEnumData<YGOverflow>(flags, overflowOffset);
|
return facebook::yoga::detail::getEnumData<YGOverflow>(
|
||||||
|
flags, overflowOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGOverflow> overflow() { return {*this, overflowOffset}; }
|
BitfieldRef<YGOverflow> overflow() { return {*this, overflowOffset}; }
|
||||||
|
|
||||||
YGDisplay display() const {
|
YGDisplay display() const {
|
||||||
return getEnumData<YGDisplay>(flags, displayOffset);
|
return facebook::yoga::detail::getEnumData<YGDisplay>(flags, displayOffset);
|
||||||
}
|
}
|
||||||
BitfieldRef<YGDisplay> display() { return {*this, displayOffset}; }
|
BitfieldRef<YGDisplay> display() { return {*this, displayOffset}; }
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user