From 7406276a5bf916cf4e564b603555244f144e5813 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 11 Jan 2019 03:09:11 -0800 Subject: [PATCH] Remove enum count macros Summary: @public Removes all `YG...Count` macros for enums and replaces them with `facebook::yoga::enums::count()`. This removes the need to manually maintain enum counts. Same as D13597449, working around a defect in clang < 3.9 Reviewed By: amir-shalem Differential Revision: D13634622 fbshipit-source-id: 344dc70e167b0caf746fe396cedd200f54e52219 --- .../fabric/components/view/conversions.h | 27 ++--- ReactCommon/yoga/yoga/YGConfig.h | 3 +- ReactCommon/yoga/yoga/YGEnums.h | 99 +++++++++++++------ ReactCommon/yoga/yoga/YGNode.cpp | 3 +- ReactCommon/yoga/yoga/YGNodePrint.cpp | 7 +- ReactCommon/yoga/yoga/YGStyle.h | 4 +- ReactCommon/yoga/yoga/Yoga-internal.h | 3 +- ReactCommon/yoga/yoga/Yoga.cpp | 14 ++- 8 files changed, 101 insertions(+), 59 deletions(-) diff --git a/ReactCommon/fabric/components/view/conversions.h b/ReactCommon/fabric/components/view/conversions.h index 630b88417..4a4eaa5ea 100644 --- a/ReactCommon/fabric/components/view/conversions.h +++ b/ReactCommon/fabric/components/view/conversions.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -445,7 +446,7 @@ inline void fromDynamic(const folly::dynamic &value, BorderStyle &result) { } inline std::string toString( - const std::array &dimensions) { + const std::array()> &dimensions) { return "{" + folly::to(dimensions[0]) + ", " + folly::to(dimensions[1]) + "}"; } @@ -455,7 +456,8 @@ inline std::string toString(const std::array &position) { folly::to(position[1]) + "}"; } -inline std::string toString(const std::array &edges) { +inline std::string toString( + const std::array()> &edges) { return "{" + folly::to(edges[0]) + ", " + folly::to(edges[1]) + ", " + folly::to(edges[2]) + ", " + @@ -590,20 +592,21 @@ inline std::string toString(const YGStyle::Dimensions &value) { } inline std::string toString(const YGStyle::Edges &value) { - static std::array names = {{"left", - "top", - "right", - "bottom", - "start", - "end", - "horizontal", - "vertical", - "all"}}; + static std::array()> names = { + {"left", + "top", + "right", + "bottom", + "start", + "end", + "horizontal", + "vertical", + "all"}}; auto result = std::string{}; auto separator = std::string{", "}; - for (auto i = 0; i < YGEdgeCount; i++) { + for (auto i = 0; i < yoga::enums::count(); i++) { YGValue v = value[i]; if (v.unit == YGUnitUndefined) { continue; diff --git a/ReactCommon/yoga/yoga/YGConfig.h b/ReactCommon/yoga/yoga/YGConfig.h index c9b871fe8..00415ce97 100644 --- a/ReactCommon/yoga/yoga/YGConfig.h +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/YGEnums.h b/ReactCommon/yoga/yoga/YGEnums.h index 00be50448..f06b0e045 100644 --- a/ReactCommon/yoga/yoga/YGEnums.h +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/YGNode.cpp b/ReactCommon/yoga/yoga/YGNode.cpp index 022e60676..255db9201 100644 --- a/ReactCommon/yoga/yoga/YGNode.cpp +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/YGNodePrint.cpp b/ReactCommon/yoga/yoga/YGNodePrint.cpp index 1c0c2708d..4e02deeee 100644 --- a/ReactCommon/yoga/yoga/YGNodePrint.cpp +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/YGStyle.h b/ReactCommon/yoga/yoga/YGStyle.h index 9193c69da..e540635d0 100644 --- a/ReactCommon/yoga/yoga/YGStyle.h +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/Yoga-internal.h b/ReactCommon/yoga/yoga/Yoga-internal.h index 50d96dc2c..1932cf1ac 100644 --- a/ReactCommon/yoga/yoga/Yoga-internal.h +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index fc9bb0da4..0d11c7a3f 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/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 ""; }