diff --git a/yoga/YGConfig.h b/yoga/YGConfig.h index c9b871fe..00415ce9 100644 --- a/yoga/YGConfig.h +++ b/yoga/YGConfig.h @@ -10,7 +10,8 @@ #include "Yoga.h" struct YGConfig { - std::array experimentalFeatures = {}; + std::array()> + experimentalFeatures = {}; bool useWebDefaults = false; bool useLegacyStretchBehaviour = false; bool shouldDiffLayoutWithoutLegacyStretchBehaviour = false; diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index 00be5044..f06b0e04 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -8,14 +8,52 @@ #include "YGMacros.h" +#ifdef __cplusplus +namespace facebook { +namespace yoga { +namespace enums { + +template +constexpr int count(); // can't use `= delete` due to a defect in clang < 3.9 + +namespace detail { +template +constexpr int n() { + return sizeof...(xs); +} +} // namespace detail + +} // namespace enums +} // namespace yoga +} // namespace facebook +#endif + #define YG_ENUM_DECL(NAME, ...) \ typedef YG_ENUM_BEGIN(NAME){__VA_ARGS__} YG_ENUM_END(NAME); \ WIN_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 { \ + namespace yoga { \ + namespace enums { \ + template <> \ + constexpr int count() { \ + return detail::n<__VA_ARGS__>(); \ + } \ + } \ + } \ + } \ + YG_EXTERN_C_BEGIN +#else +#define YG_ENUM_SEQ_DECL YG_ENUM_DECL +#endif + YG_EXTERN_C_BEGIN -#define YGAlignCount 8 -YG_ENUM_DECL( +YG_ENUM_SEQ_DECL( YGAlign, YGAlignAuto, YGAlignFlexStart, @@ -26,17 +64,17 @@ YG_ENUM_DECL( YGAlignSpaceBetween, YGAlignSpaceAround); -#define YGDimensionCount 2 -YG_ENUM_DECL(YGDimension, YGDimensionWidth, YGDimensionHeight) +YG_ENUM_SEQ_DECL(YGDimension, YGDimensionWidth, YGDimensionHeight) -#define YGDirectionCount 3 -YG_ENUM_DECL(YGDirection, YGDirectionInherit, YGDirectionLTR, YGDirectionRTL) +YG_ENUM_SEQ_DECL( + YGDirection, + YGDirectionInherit, + YGDirectionLTR, + YGDirectionRTL) -#define YGDisplayCount 2 -YG_ENUM_DECL(YGDisplay, YGDisplayFlex, YGDisplayNone) +YG_ENUM_SEQ_DECL(YGDisplay, YGDisplayFlex, YGDisplayNone) -#define YGEdgeCount 9 -YG_ENUM_DECL( +YG_ENUM_SEQ_DECL( YGEdge, YGEdgeLeft, YGEdgeTop, @@ -48,19 +86,16 @@ YG_ENUM_DECL( YGEdgeVertical, YGEdgeAll) -#define YGExperimentalFeatureCount 1 -YG_ENUM_DECL(YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis) +YG_ENUM_SEQ_DECL(YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis) -#define YGFlexDirectionCount 4 -YG_ENUM_DECL( +YG_ENUM_SEQ_DECL( YGFlexDirection, YGFlexDirectionColumn, YGFlexDirectionColumnReverse, YGFlexDirectionRow, YGFlexDirectionRowReverse) -#define YGJustifyCount 6 -YG_ENUM_DECL( +YG_ENUM_SEQ_DECL( YGJustify, YGJustifyFlexStart, YGJustifyCenter, @@ -69,8 +104,7 @@ YG_ENUM_DECL( YGJustifySpaceAround, YGJustifySpaceEvenly) -#define YGLogLevelCount 6 -YG_ENUM_DECL( +YG_ENUM_SEQ_DECL( YGLogLevel, YGLogLevelError, YGLogLevelWarn, @@ -79,35 +113,38 @@ YG_ENUM_DECL( YGLogLevelVerbose, YGLogLevelFatal) -#define YGMeasureModeCount 3 -YG_ENUM_DECL( +YG_ENUM_SEQ_DECL( YGMeasureMode, YGMeasureModeUndefined, YGMeasureModeExactly, YGMeasureModeAtMost) -#define YGNodeTypeCount 2 -YG_ENUM_DECL(YGNodeType, YGNodeTypeDefault, YGNodeTypeText) +YG_ENUM_SEQ_DECL(YGNodeType, YGNodeTypeDefault, YGNodeTypeText) -#define YGOverflowCount 3 -YG_ENUM_DECL(YGOverflow, YGOverflowVisible, YGOverflowHidden, YGOverflowScroll) +YG_ENUM_SEQ_DECL( + YGOverflow, + YGOverflowVisible, + YGOverflowHidden, + YGOverflowScroll) -#define YGPositionTypeCount 2 -YG_ENUM_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute) +YG_ENUM_SEQ_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute) -#define YGPrintOptionsCount 3 YG_ENUM_DECL( YGPrintOptions, YGPrintOptionsLayout = 1, YGPrintOptionsStyle = 2, YGPrintOptionsChildren = 4) -#define YGUnitCount 4 -YG_ENUM_DECL(YGUnit, YGUnitUndefined, YGUnitPoint, YGUnitPercent, YGUnitAuto) +YG_ENUM_SEQ_DECL( + YGUnit, + YGUnitUndefined, + YGUnitPoint, + YGUnitPercent, + YGUnitAuto) -#define YGWrapCount 3 -YG_ENUM_DECL(YGWrap, YGWrapNoWrap, YGWrapWrap, YGWrapWrapReverse) +YG_ENUM_SEQ_DECL(YGWrap, YGWrapNoWrap, YGWrapWrap, YGWrapWrapReverse) YG_EXTERN_C_END #undef YG_ENUM_DECL +#undef YG_ENUM_SEQ_DECL diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 022e6067..255db920 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -313,7 +313,8 @@ YGValue YGNode::resolveFlexBasisPtr() const { } void YGNode::resolveDimension() { - for (uint32_t dim = YGDimensionWidth; dim < YGDimensionCount; dim++) { + using namespace yoga; + for (int dim = YGDimensionWidth; dim < enums::count(); dim++) { if (!getStyle().maxDimensions[dim].isUndefined() && YGValueEqual( getStyle().maxDimensions[dim], style_.minDimensions[dim])) { diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 1c0c2708..4e02deee 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -20,8 +20,7 @@ static void indent(string& base, uint32_t level) { } } -static bool areFourValuesEqual( - const facebook::yoga::detail::Values& four) { +static bool areFourValuesEqual(const YGStyle::Edges& four) { return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) && YGValueEqual(four[0], four[3]); } @@ -86,7 +85,7 @@ static void appendNumberIfNotZero( static void appendEdges( string& base, const string& key, - const facebook::yoga::detail::Values& edges) { + const YGStyle::Edges& edges) { if (areFourValuesEqual(edges)) { appendNumberIfNotZero(base, key, edges[YGEdgeLeft]); } else { @@ -100,7 +99,7 @@ static void appendEdges( static void appendEdgeIfNotUndefined( string& base, const string& str, - const facebook::yoga::detail::Values& edges, + const YGStyle::Edges& edges, const YGEdge edge) { appendNumberIfNotUndefined( base, diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index 9193c69d..e540635d 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -9,6 +9,7 @@ #include #include #include "CompactValue.h" +#include "YGEnums.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" #include "Yoga.h" @@ -29,7 +30,8 @@ private: public: using Dimensions = facebook::yoga::detail::Values<2>; - using Edges = facebook::yoga::detail::Values; + using Edges = + facebook::yoga::detail::Values()>; /* Some platforms don't support enum bitfields, so please use BITFIELD_ENUM_SIZED(BITS_COUNT) */ diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 50d96dc2..1932cf1a 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -149,6 +149,7 @@ static const float kWebDefaultFlexShrink = 1.0f; extern bool YGFloatsEqual(const float a, const float b); extern bool YGValueEqual(const YGValue a, const YGValue b); extern facebook::yoga::detail::CompactValue YGComputedEdgeValue( - const facebook::yoga::detail::Values& edges, + const facebook::yoga::detail::Values< + facebook::yoga::enums::count()>& edges, YGEdge edge, facebook::yoga::detail::CompactValue defaultValue); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index fc9bb0da..0d11c7a3 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -105,7 +105,7 @@ bool YGFloatIsUndefined(const float value) { } detail::CompactValue YGComputedEdgeValue( - const facebook::yoga::detail::Values& edges, + const YGStyle::Edges& edges, YGEdge edge, detail::CompactValue defaultValue) { if (!edges[edge].isUndefined()) { @@ -3546,14 +3546,12 @@ static const char* YGSpacer(const unsigned long level) { static const char* YGMeasureModeName( const YGMeasureMode mode, const bool performLayout) { - const char* kMeasureModeNames[YGMeasureModeCount] = { - "UNDEFINED", "EXACTLY", "AT_MOST"}; - const char* kLayoutModeNames[YGMeasureModeCount] = {"LAY_UNDEFINED", - "LAY_EXACTLY", - "LAY_AT_" - "MOST"}; + constexpr auto N = enums::count(); + const char* kMeasureModeNames[N] = {"UNDEFINED", "EXACTLY", "AT_MOST"}; + const char* kLayoutModeNames[N] = { + "LAY_UNDEFINED", "LAY_EXACTLY", "LAY_AT_MOST"}; - if (mode >= YGMeasureModeCount) { + if (mode >= N) { return ""; }