From 89394a2dd6ccfa34466403e3a476cbf99e98fa52 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Sat, 24 Nov 2018 16:23:54 -0800 Subject: [PATCH 01/53] Data types for marker API Summary: @public Adds types for a marker API in Yoga. This will allow us to register callbacks that Yoga can use to log performance data without hard-coding the backend system for that. Reviewed By: SidharthGuglani Differential Revision: D13118830 fbshipit-source-id: b42a42c609f0cf66212186f7f20ee572522d59e3 --- yoga/YGConfig.h | 4 +++- yoga/YGMarker.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 yoga/YGMarker.h diff --git a/yoga/YGConfig.h b/yoga/YGConfig.h index 941e0dcd..b5f3c5fd 100644 --- a/yoga/YGConfig.h +++ b/yoga/YGConfig.h @@ -6,6 +6,7 @@ * */ #pragma once +#include "YGMarker.h" #include "Yoga-internal.h" #include "Yoga.h" @@ -14,11 +15,12 @@ struct YGConfig { bool useWebDefaults = false; bool useLegacyStretchBehaviour = false; bool shouldDiffLayoutWithoutLegacyStretchBehaviour = false; + bool printTree = false; float pointScaleFactor = 1.0f; YGLogger logger; YGCloneNodeFunc cloneNodeCallback = nullptr; void* context = nullptr; - bool printTree = false; + YGMarkerCallbacks markerCallbacks = {nullptr, nullptr}; YGConfig(YGLogger logger); }; diff --git a/yoga/YGMarker.h b/yoga/YGMarker.h new file mode 100644 index 00000000..00c582ab --- /dev/null +++ b/yoga/YGMarker.h @@ -0,0 +1,32 @@ +/** + * Copyright (c) Facebook, Inc. and its 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 "YGMacros.h" + +YG_EXTERN_C_BEGIN + +typedef struct YGNode* YGNodeRef; + +typedef YG_ENUM_BEGIN(YGMarkerType) {} +YG_ENUM_END(YGMarkerType); + +typedef union { + int unused; +} YGMarkerData; + +typedef struct { + // accepts marker type, a node ref, and marker data (depends on marker type) + // can return a handle or id that Yoga will pass to endMarker + void* (*startMarker)(YGMarkerType, YGNodeRef, YGMarkerData); + // accepts marker type, a node ref, marker data, and marker id as returned + // by startMarker + void (*endMarker)(YGMarkerType, YGNodeRef, YGMarkerData, void* id); +} YGMarkerCallbacks; + +YG_EXTERN_C_END -- 2.50.1.windows.1 From 8e48edaa0bf25f38052a3b3297705e61416701b0 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Mon, 26 Nov 2018 07:26:28 -0800 Subject: [PATCH 02/53] calling markDirtyAndPropogate when setting isReferenceBaseline value Summary: @public Marking the node as dirty when isReferenceBaseline property is changed Reviewed By: davidaurelio Differential Revision: D13147742 fbshipit-source-id: 3bbff1cfceeadfbf77380519e4638f2984fc2009 --- yoga/Yoga.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 10f27bf0..491cc1ee 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -381,7 +381,10 @@ void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) { } void YGNodeSetIsReferenceBaseline(YGNodeRef node, bool isReferenceBaseline) { - node->setIsReferenceBaseline(isReferenceBaseline); + if (node->isReferenceBaseline() != isReferenceBaseline) { + node->setIsReferenceBaseline(isReferenceBaseline); + node->markDirtyAndPropogate(); + } } bool YGNodeIsReferenceBaseline(YGNodeRef node) { -- 2.50.1.windows.1 From 9725d5b21b550da8d17453047d30d8e53df08bfe Mon Sep 17 00:00:00 2001 From: Tomas Reimers Date: Mon, 26 Nov 2018 16:00:37 -0800 Subject: [PATCH 03/53] Create a recursive free with cleanup function Reviewed By: davidaurelio Differential Revision: D13119307 fbshipit-source-id: 162bb4fd6d7620f61cbac010d0dc236d81738b71 --- yoga/Yoga.cpp | 11 ++++++++++- yoga/Yoga.h | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 491cc1ee..463107ee 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -319,7 +319,9 @@ static void YGConfigFreeRecursive(const YGNodeRef root) { } } -void YGNodeFreeRecursive(const YGNodeRef root) { +void YGNodeFreeRecursiveWithCleanupFunc( + const YGNodeRef root, + YGNodeCleanupFunc cleanup) { while (YGNodeGetChildCount(root) > 0) { const YGNodeRef child = YGNodeGetChild(root, 0); if (child->getOwner() != root) { @@ -329,9 +331,16 @@ void YGNodeFreeRecursive(const YGNodeRef root) { YGNodeRemoveChild(root, child); YGNodeFreeRecursive(child); } + if (cleanup != nullptr) { + cleanup(root); + } YGNodeFree(root); } +void YGNodeFreeRecursive(const YGNodeRef root) { + return YGNodeFreeRecursiveWithCleanupFunc(root, nullptr); +} + void YGNodeReset(const YGNodeRef node) { YGAssertWithNode( node, diff --git a/yoga/Yoga.h b/yoga/Yoga.h index dddab8bb..04e0bf1d 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -70,6 +70,7 @@ typedef float ( *YGBaselineFunc)(YGNodeRef node, const float width, const float height); typedef void (*YGDirtiedFunc)(YGNodeRef node); typedef void (*YGPrintFunc)(YGNodeRef node); +typedef void (*YGNodeCleanupFunc)(YGNodeRef node); typedef int (*YGLogger)( const YGConfigRef config, const YGNodeRef node, @@ -84,6 +85,9 @@ WIN_EXPORT YGNodeRef YGNodeNew(void); WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config); WIN_EXPORT YGNodeRef YGNodeClone(const YGNodeRef node); WIN_EXPORT void YGNodeFree(const YGNodeRef node); +WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( + const YGNodeRef node, + YGNodeCleanupFunc cleanup); WIN_EXPORT void YGNodeFreeRecursive(const YGNodeRef node); WIN_EXPORT void YGNodeReset(const YGNodeRef node); WIN_EXPORT int32_t YGNodeGetInstanceCount(void); -- 2.50.1.windows.1 From 6d8ee777917971a5605379af0e901cda3681add6 Mon Sep 17 00:00:00 2001 From: Tnarita0000 Date: Tue, 27 Nov 2018 03:39:54 -0800 Subject: [PATCH 04/53] Fix typo 'laid our' to 'laid out' (#833) Summary: I've fixed typo `laid our` to `laid out` in [`website/contents/properties/layout-direction.md`]. Pull Request resolved: https://github.com/facebook/yoga/pull/833 Differential Revision: D13196468 Pulled By: passy fbshipit-source-id: 8b51e0d93fd0b6b131b7ea9446fff28ffeca9764 --- website/contents/properties/layout-direction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/contents/properties/layout-direction.md b/website/contents/properties/layout-direction.md index 869b5d47..76c43fd2 100644 --- a/website/contents/properties/layout-direction.md +++ b/website/contents/properties/layout-direction.md @@ -14,10 +14,10 @@ refers to `right`. When localizing your apps for markets with RTL languages you should customize this by either by passing a direction to the `CalculateLayout` call or by setting the direction on the root node. -**LTR (DEFAULT)** Text and children and laid our from left to right. Margin and +**LTR (DEFAULT)** Text and children and laid out from left to right. Margin and padding applied the start of an element are applied on the left side. -**RTL** Text and children and laid our from right to left. Margin and +**RTL** Text and children and laid out from right to left. Margin and padding applied the start of an element are applied on the right side. -- 2.50.1.windows.1 From bdae838516856b1548b9c237f027002a296b3c93 Mon Sep 17 00:00:00 2001 From: Taras Tsugrii Date: Tue, 27 Nov 2018 15:13:56 -0800 Subject: [PATCH 05/53] Sort build file loads. Summary: drop-conflicts Reviewed By: passy Differential Revision: D13176350 fbshipit-source-id: 0f875a6c0f1eca2f992026bb2b2d0851f90f5d2f --- android/sample/BUCK | 2 +- csharp/BUCK | 2 +- lib/appcompat/BUCK | 2 +- lib/soloader/BUCK | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/sample/BUCK b/android/sample/BUCK index 0989fcd6..7a408bb9 100644 --- a/android/sample/BUCK +++ b/android/sample/BUCK @@ -4,8 +4,8 @@ # This source code is licensed under the license found in the # LICENSE-examples file in the root directory of this source tree. -load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_RES_TARGET", "ANDROID_SAMPLE_JAVA_TARGET", "ANDROID_SAMPLE_RES_TARGET", "yoga_android_binary", "yoga_android_resource") +load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") yoga_android_binary( name = "sample", diff --git a/csharp/BUCK b/csharp/BUCK index 685b227f..0f8a0bf8 100644 --- a/csharp/BUCK +++ b/csharp/BUCK @@ -3,7 +3,6 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") load( "//tools/build_defs/oss:yoga_defs.bzl", "BASE_COMPILER_FLAGS", @@ -11,6 +10,7 @@ load( "yoga_cxx_library", "yoga_dep", ) +load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") COMPILER_FLAGS = BASE_COMPILER_FLAGS + ["-std=c++11"] diff --git a/lib/appcompat/BUCK b/lib/appcompat/BUCK index b3262494..670c5f20 100644 --- a/lib/appcompat/BUCK +++ b/lib/appcompat/BUCK @@ -3,8 +3,8 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") load("//tools/build_defs/oss:yoga_defs.bzl", "YOGA_ROOTS") +load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") fb_native.android_prebuilt_aar( name = "appcompat", diff --git a/lib/soloader/BUCK b/lib/soloader/BUCK index 04e2f5ff..5f3cc331 100644 --- a/lib/soloader/BUCK +++ b/lib/soloader/BUCK @@ -3,8 +3,8 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") load("//tools/build_defs/oss:yoga_defs.bzl", "YOGA_ROOTS") +load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") fb_native.android_prebuilt_aar( name = "soloader", -- 2.50.1.windows.1 From 6f6e0ce339cd310fd9ba7f4f9b068684331e0938 Mon Sep 17 00:00:00 2001 From: Eddie Zhang Date: Thu, 29 Nov 2018 11:13:36 -0800 Subject: [PATCH 06/53] Fix typo in Yoga Layout documentation Summary: Found and fixed typo on https://yogalayout.com/docs/justify-content/ Reviewed By: danielbuechele Differential Revision: D13199988 fbshipit-source-id: 029cf812f09c48822ec11b054bf0c987f718191d --- website/contents/properties/justify-content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/contents/properties/justify-content.md b/website/contents/properties/justify-content.md index af159e66..84ccb335 100644 --- a/website/contents/properties/justify-content.md +++ b/website/contents/properties/justify-content.md @@ -22,7 +22,7 @@ remaining space between the children. **SPACE AROUND** Evenly space of children across the container's main axis, distributing remaining space around the children. Compared to `space between` using -`Sspace around` will result in space being distributed to the beginning of +`space around` will result in space being distributed to the beginning of the first child and end of the last child. -- 2.50.1.windows.1 From 98c1c180afdb053e13e7212e979191f73ac6ad59 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 29 Nov 2018 11:35:34 -0800 Subject: [PATCH 07/53] Remove extraneous file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: @public This file shouldn’t be here Reviewed By: SidharthGuglani Differential Revision: D13255658 fbshipit-source-id: 1b40ab674bbf451d04797516a24c3bd2fef7222d --- .../yoga/src/main/cpp/yoga/Yoga-internal.h | 121 ------------------ 1 file changed, 121 deletions(-) delete mode 100644 fbandroid/libraries/components/lib/yoga/src/main/cpp/yoga/Yoga-internal.h diff --git a/fbandroid/libraries/components/lib/yoga/src/main/cpp/yoga/Yoga-internal.h b/fbandroid/libraries/components/lib/yoga/src/main/cpp/yoga/Yoga-internal.h deleted file mode 100644 index ccc9e197..00000000 --- a/fbandroid/libraries/components/lib/yoga/src/main/cpp/yoga/Yoga-internal.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#pragma once -#include -#include -#include -#include -#include "Yoga.h" - -using YGVector = std::vector; - -YG_EXTERN_C_BEGIN - -WIN_EXPORT float YGRoundValueToPixelGrid( - const float value, - const float pointScaleFactor, - const bool forceCeil, - const bool forceFloor); - -YG_EXTERN_C_END - -extern const std::array trailing; -extern const std::array leading; -extern bool YGValueEqual(const YGValue a, const YGValue b); -extern const YGValue YGValueUndefined; -extern const YGValue YGValueAuto; -extern const YGValue YGValueZero; - -template -bool YGValueArrayEqual( - const std::array val1, - const std::array val2) { - bool areEqual = true; - for (uint32_t i = 0; i < size && areEqual; ++i) { - areEqual = YGValueEqual(val1[i], val2[i]); - } - return areEqual; -} - -const YGValue kYGValueUndefined = {YGUndefined, YGUnitUndefined}; -const YGValue kYGValueAuto = {YGUndefined, YGUnitAuto}; -const std::array kYGDefaultEdgeValuesUnit = { - {kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined}}; -const std::array kYGDefaultDimensionValuesAutoUnit = { - {kYGValueAuto, kYGValueAuto}}; -const std::array kYGDefaultDimensionValuesUnit = { - {kYGValueUndefined, kYGValueUndefined}}; - -struct YGCachedMeasurement { - float availableWidth; - float availableHeight; - YGMeasureMode widthMeasureMode; - YGMeasureMode heightMeasureMode; - - float computedWidth; - float computedHeight; - - bool operator==(YGCachedMeasurement measurement) const { - bool isEqual = widthMeasureMode == measurement.widthMeasureMode && - heightMeasureMode == measurement.heightMeasureMode; - - if (!std::isnan(availableWidth) || - !std::isnan(measurement.availableWidth)) { - isEqual = isEqual && availableWidth == measurement.availableWidth; - } - if (!std::isnan(availableHeight) || - !std::isnan(measurement.availableHeight)) { - isEqual = isEqual && availableHeight == measurement.availableHeight; - } - if (!std::isnan(computedWidth) || !std::isnan(measurement.computedWidth)) { - isEqual = isEqual && computedWidth == measurement.computedWidth; - } - if (!std::isnan(computedHeight) || - !std::isnan(measurement.computedHeight)) { - isEqual = isEqual && computedHeight == measurement.computedHeight; - } - - return isEqual; - } -}; - -// This value was chosen based on empiracle data. Even the most complicated -// layouts should not require more than 16 entries to fit within the cache. -#define YG_MAX_CACHED_RESULT_COUNT 16 - -struct YGConfig { - bool experimentalFeatures[YGExperimentalFeatureCount + 1]; - bool useWebDefaults; - bool useLegacyStretchBehaviour; - bool shouldDiffLayoutWithoutLegacyStretchBehaviour; - float pointScaleFactor; - YGLogger logger; - YGNodeClonedFunc cloneNodeCallback; - void* context; -}; - -static const float kDefaultFlexGrow = 0.0f; -static const float kDefaultFlexShrink = 0.0f; -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 const YGValue* YGComputedEdgeValue( - const std::array& edges, - const YGEdge edge, - const YGValue* const defaultValue); -- 2.50.1.windows.1 From b9972cee6e9958076a2d8ad2e1054d207a229809 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 29 Nov 2018 11:35:34 -0800 Subject: [PATCH 08/53] Adjust yearless format for MIT license Summary: @public Adjust license headers throughout the project Reviewed By: SidharthGuglani Differential Revision: D13255691 fbshipit-source-id: 98be2aa372a94e7a54a65e3d64e5c6a436b18083 --- YogaKit/Source/UIView+Yoga.h | 5 ++--- YogaKit/Source/YGLayout+Private.h | 5 ++--- YogaKit/Source/YGLayout.h | 5 ++--- benchmark/YGBenchmark.c | 5 ++--- csharp/Yoga/YGInterop.cpp | 5 ++--- csharp/Yoga/YGInterop.h | 5 ++--- csharp/Yoga/dllmain.cpp | 5 ++--- csharp/Yoga/stdafx.cpp | 5 ++--- csharp/Yoga/stdafx.h | 5 ++--- csharp/Yoga/targetver.h | 5 ++--- java/jni/YGJNI.cpp | 9 ++++----- javascript/sources/Config.cc | 5 ++--- javascript/sources/Node.cc | 5 ++--- javascript/sources/global.cc | 5 ++--- javascript/sources/nbind.cc | 5 ++--- lib/fb/src/main/cpp/assert.cpp | 7 +++---- lib/fb/src/main/cpp/include/fb/ALog.h | 7 +++---- lib/fb/src/main/cpp/include/fb/Countable.h | 7 +++---- lib/fb/src/main/cpp/include/fb/Environment.h | 7 +++---- lib/fb/src/main/cpp/include/fb/ProgramLocation.h | 7 +++---- lib/fb/src/main/cpp/include/fb/RefPtr.h | 7 +++---- lib/fb/src/main/cpp/include/fb/StaticInitialized.h | 7 +++---- lib/fb/src/main/cpp/include/fb/ThreadLocal.h | 7 +++---- lib/fb/src/main/cpp/include/fb/assert.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Boxed.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/ByteBuffer.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Common.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Context.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses-inl.h | 9 ++++----- lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Exceptions.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/File.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Hybrid.h | 9 ++++----- lib/fb/src/main/cpp/include/fb/fbjni/Iterator-inl.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Iterator.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/JThread.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Meta-forward.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/Meta-inl.h | 9 ++++----- lib/fb/src/main/cpp/include/fb/fbjni/Meta.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/MetaConvert.h | 8 ++++++-- lib/fb/src/main/cpp/include/fb/fbjni/NativeRunnable.h | 7 +++---- .../main/cpp/include/fb/fbjni/ReferenceAllocators-inl.h | 7 +++---- .../src/main/cpp/include/fb/fbjni/ReferenceAllocators.h | 7 +++---- .../src/main/cpp/include/fb/fbjni/References-forward.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/References-inl.h | 9 ++++----- lib/fb/src/main/cpp/include/fb/fbjni/References.h | 8 +++----- lib/fb/src/main/cpp/include/fb/fbjni/Registration-inl.h | 9 ++++----- lib/fb/src/main/cpp/include/fb/fbjni/Registration.h | 7 +++---- lib/fb/src/main/cpp/include/fb/fbjni/TypeTraits.h | 7 +++---- lib/fb/src/main/cpp/include/fb/lyra.h | 8 ++++++-- lib/fb/src/main/cpp/include/fb/noncopyable.h | 7 +++---- lib/fb/src/main/cpp/include/fb/nonmovable.h | 7 +++---- lib/fb/src/main/cpp/include/fb/visibility.h | 7 +++---- lib/fb/src/main/cpp/include/jni/Countable.h | 7 +++---- lib/fb/src/main/cpp/include/jni/GlobalReference.h | 7 +++---- lib/fb/src/main/cpp/include/jni/LocalReference.h | 7 +++---- lib/fb/src/main/cpp/include/jni/LocalString.h | 7 +++---- lib/fb/src/main/cpp/include/jni/Registration.h | 7 +++---- lib/fb/src/main/cpp/include/jni/WeakReference.h | 7 +++---- lib/fb/src/main/cpp/include/jni/jni_helpers.h | 7 +++---- lib/fb/src/main/cpp/jni/ByteBuffer.cpp | 7 +++---- lib/fb/src/main/cpp/jni/Countable.cpp | 7 +++---- lib/fb/src/main/cpp/jni/Environment.cpp | 7 +++---- lib/fb/src/main/cpp/jni/Exceptions.cpp | 7 +++---- lib/fb/src/main/cpp/jni/Hybrid.cpp | 7 +++---- lib/fb/src/main/cpp/jni/LocalString.cpp | 7 +++---- lib/fb/src/main/cpp/jni/OnLoad.cpp | 7 +++---- lib/fb/src/main/cpp/jni/References.cpp | 7 +++---- lib/fb/src/main/cpp/jni/WeakReference.cpp | 7 +++---- lib/fb/src/main/cpp/jni/fbjni.cpp | 7 +++---- lib/fb/src/main/cpp/jni/jni_helpers.cpp | 7 +++---- lib/fb/src/main/cpp/log.cpp | 7 +++---- lib/fb/src/main/cpp/lyra/lyra.cpp | 8 ++++++-- lib/fb/src/main/cpp/onload.cpp | 7 +++---- lib/jni/jni.h | 5 ++--- tests/YGAbsolutePositionTest.cpp | 5 ++--- tests/YGAlignBaselineTest.cpp | 9 ++++----- tests/YGAlignContentTest.cpp | 5 ++--- tests/YGAlignItemsTest.cpp | 9 ++++----- tests/YGAlignSelfTest.cpp | 5 ++--- tests/YGAndroidNewsFeed.cpp | 5 ++--- tests/YGAspectRatioTest.cpp | 5 ++--- tests/YGBaselineFuncTest.cpp | 5 ++--- tests/YGBorderTest.cpp | 5 ++--- tests/YGComputedMarginTest.cpp | 9 ++++----- tests/YGComputedPaddingTest.cpp | 9 ++++----- tests/YGDefaultValuesTest.cpp | 5 ++--- tests/YGDimensionTest.cpp | 5 ++--- tests/YGDirtiedTest.cpp | 5 ++--- tests/YGDirtyMarkingTest.cpp | 5 ++--- tests/YGDisplayTest.cpp | 5 ++--- tests/YGEdgeTest.cpp | 5 ++--- tests/YGFlexDirectionTest.cpp | 5 ++--- tests/YGFlexTest.cpp | 9 ++++----- tests/YGFlexWrapTest.cpp | 5 ++--- tests/YGHadOverflowTest.cpp | 8 ++++++-- tests/YGInfiniteHeightTest.cpp | 5 ++--- tests/YGJustifyContentTest.cpp | 4 ++-- tests/YGLayoutDiffingTest.cpp | 5 ++--- tests/YGLoggerTest.cpp | 9 ++++----- tests/YGMarginTest.cpp | 5 ++--- tests/YGMeasureCacheTest.cpp | 5 ++--- tests/YGMeasureModeTest.cpp | 5 ++--- tests/YGMeasureTest.cpp | 9 ++++----- tests/YGMinMaxDimensionTest.cpp | 5 ++--- tests/YGNodeChildTest.cpp | 5 ++--- tests/YGPaddingTest.cpp | 9 ++++----- tests/YGPercentageTest.cpp | 5 ++--- tests/YGPersistenceTest.cpp | 5 ++--- tests/YGRelayoutTest.cpp | 5 ++--- tests/YGRoundingFunctionTest.cpp | 9 ++++----- tests/YGRoundingMeasureFuncTest.cpp | 5 ++--- tests/YGRoundingTest.cpp | 5 ++--- tests/YGSizeOverflowTest.cpp | 5 ++--- tests/YGStyleTest.cpp | 5 ++--- tests/YGTraversalTest.cpp | 5 ++--- tests/YGTreeMutationTest.cpp | 5 ++--- tests/YGZeroOutLayoutRecursivlyTest.cpp | 5 ++--- yoga/Utils.cpp | 9 ++++----- yoga/Utils.h | 5 ++--- yoga/YGConfig.cpp | 9 ++++----- yoga/YGConfig.h | 9 ++++----- yoga/YGEnums.cpp | 5 ++--- yoga/YGEnums.h | 5 ++--- yoga/YGFloatOptional.cpp | 9 ++++----- yoga/YGFloatOptional.h | 9 ++++----- yoga/YGLayout.cpp | 9 ++++----- yoga/YGLayout.h | 9 ++++----- yoga/YGMacros.h | 5 ++--- yoga/YGMarker.h | 5 ++--- yoga/YGNode.cpp | 9 ++++----- yoga/YGNode.h | 9 ++++----- yoga/YGNodePrint.cpp | 7 +++---- yoga/YGNodePrint.h | 4 ++-- yoga/YGStyle.cpp | 9 ++++----- yoga/YGStyle.h | 9 ++++----- yoga/Yoga-internal.h | 9 ++++----- yoga/Yoga.cpp | 9 ++++----- yoga/Yoga.h | 9 ++++----- 140 files changed, 407 insertions(+), 526 deletions(-) diff --git a/YogaKit/Source/UIView+Yoga.h b/YogaKit/Source/UIView+Yoga.h index 68675188..6b012bb6 100644 --- a/YogaKit/Source/UIView+Yoga.h +++ b/YogaKit/Source/UIView+Yoga.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #import "YGLayout.h" #import diff --git a/YogaKit/Source/YGLayout+Private.h b/YogaKit/Source/YGLayout+Private.h index e680222d..601eda18 100644 --- a/YogaKit/Source/YGLayout+Private.h +++ b/YogaKit/Source/YGLayout+Private.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #import "YGLayout.h" #import diff --git a/YogaKit/Source/YGLayout.h b/YogaKit/Source/YGLayout.h index 37aa2345..8aff3b5e 100644 --- a/YogaKit/Source/YGLayout.h +++ b/YogaKit/Source/YGLayout.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #import #import #import diff --git a/benchmark/YGBenchmark.c b/benchmark/YGBenchmark.c index 3198e96f..7256e8f3 100644 --- a/benchmark/YGBenchmark.c +++ b/benchmark/YGBenchmark.c @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/csharp/Yoga/YGInterop.cpp b/csharp/Yoga/YGInterop.cpp index f4fa1337..30a8979b 100644 --- a/csharp/Yoga/YGInterop.cpp +++ b/csharp/Yoga/YGInterop.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include "YGInterop.h" static YGInteropLogger gManagedLogger; diff --git a/csharp/Yoga/YGInterop.h b/csharp/Yoga/YGInterop.h index bbd0d029..597a2cc8 100644 --- a/csharp/Yoga/YGInterop.h +++ b/csharp/Yoga/YGInterop.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/csharp/Yoga/dllmain.cpp b/csharp/Yoga/dllmain.cpp index 18aee01d..88c48a02 100644 --- a/csharp/Yoga/dllmain.cpp +++ b/csharp/Yoga/dllmain.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" diff --git a/csharp/Yoga/stdafx.cpp b/csharp/Yoga/stdafx.cpp index a353183e..1d59258a 100644 --- a/csharp/Yoga/stdafx.cpp +++ b/csharp/Yoga/stdafx.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // stdafx.cpp : source file that includes just the standard includes // Yoga.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information diff --git a/csharp/Yoga/stdafx.h b/csharp/Yoga/stdafx.h index c9c782b8..3d3c3aec 100644 --- a/csharp/Yoga/stdafx.h +++ b/csharp/Yoga/stdafx.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently diff --git a/csharp/Yoga/targetver.h b/csharp/Yoga/targetver.h index 91b65674..f74769cf 100644 --- a/csharp/Yoga/targetver.h +++ b/csharp/Yoga/targetver.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once // Including SDKDDKVer.h defines the highest available Windows platform. diff --git a/java/jni/YGJNI.cpp b/java/jni/YGJNI.cpp index 8c6536d4..fb4ec3c6 100644 --- a/java/jni/YGJNI.cpp +++ b/java/jni/YGJNI.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) 2018-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/javascript/sources/Config.cc b/javascript/sources/Config.cc index f3b4ff87..60e5bafc 100644 --- a/javascript/sources/Config.cc +++ b/javascript/sources/Config.cc @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include "./Config.hh" diff --git a/javascript/sources/Node.cc b/javascript/sources/Node.cc index c684da28..108bc4b5 100644 --- a/javascript/sources/Node.cc +++ b/javascript/sources/Node.cc @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/javascript/sources/global.cc b/javascript/sources/global.cc index 1f36c07d..96096e83 100644 --- a/javascript/sources/global.cc +++ b/javascript/sources/global.cc @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include "./global.hh" diff --git a/javascript/sources/nbind.cc b/javascript/sources/nbind.cc index 0ea7e0db..c778fe8a 100644 --- a/javascript/sources/nbind.cc +++ b/javascript/sources/nbind.cc @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include "./Node.hh" diff --git a/lib/fb/src/main/cpp/assert.cpp b/lib/fb/src/main/cpp/assert.cpp index dd64bebc..be64e787 100644 --- a/lib/fb/src/main/cpp/assert.cpp +++ b/lib/fb/src/main/cpp/assert.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/lib/fb/src/main/cpp/include/fb/ALog.h b/lib/fb/src/main/cpp/include/fb/ALog.h index 164288b4..6ea846ee 100644 --- a/lib/fb/src/main/cpp/include/fb/ALog.h +++ b/lib/fb/src/main/cpp/include/fb/ALog.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - /** @file ALog.h * * Very simple android only logging. Define LOG_TAG to enable the macros. diff --git a/lib/fb/src/main/cpp/include/fb/Countable.h b/lib/fb/src/main/cpp/include/fb/Countable.h index 01afe983..b355ab67 100644 --- a/lib/fb/src/main/cpp/include/fb/Countable.h +++ b/lib/fb/src/main/cpp/include/fb/Countable.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/Environment.h b/lib/fb/src/main/cpp/include/fb/Environment.h index 55f12f95..53b14c80 100644 --- a/lib/fb/src/main/cpp/include/fb/Environment.h +++ b/lib/fb/src/main/cpp/include/fb/Environment.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/ProgramLocation.h b/lib/fb/src/main/cpp/include/fb/ProgramLocation.h index cc23ee71..57c44c1d 100644 --- a/lib/fb/src/main/cpp/include/fb/ProgramLocation.h +++ b/lib/fb/src/main/cpp/include/fb/ProgramLocation.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/RefPtr.h b/lib/fb/src/main/cpp/include/fb/RefPtr.h index e39bd026..8c22a151 100644 --- a/lib/fb/src/main/cpp/include/fb/RefPtr.h +++ b/lib/fb/src/main/cpp/include/fb/RefPtr.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/StaticInitialized.h b/lib/fb/src/main/cpp/include/fb/StaticInitialized.h index 566e02cd..c8b84dea 100644 --- a/lib/fb/src/main/cpp/include/fb/StaticInitialized.h +++ b/lib/fb/src/main/cpp/include/fb/StaticInitialized.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/ThreadLocal.h b/lib/fb/src/main/cpp/include/fb/ThreadLocal.h index 675950fc..4ea9e6ca 100644 --- a/lib/fb/src/main/cpp/include/fb/ThreadLocal.h +++ b/lib/fb/src/main/cpp/include/fb/ThreadLocal.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/assert.h b/lib/fb/src/main/cpp/include/fb/assert.h index a6b747f7..f6dce42b 100644 --- a/lib/fb/src/main/cpp/include/fb/assert.h +++ b/lib/fb/src/main/cpp/include/fb/assert.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #ifndef FBASSERT_H #define FBASSERT_H diff --git a/lib/fb/src/main/cpp/include/fb/fbjni.h b/lib/fb/src/main/cpp/include/fb/fbjni.h index 49e4f502..9f0da1ab 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Boxed.h b/lib/fb/src/main/cpp/include/fb/fbjni/Boxed.h index 71058e04..36ab9a31 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Boxed.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Boxed.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "CoreClasses.h" diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/ByteBuffer.h b/lib/fb/src/main/cpp/include/fb/fbjni/ByteBuffer.h index 61f7be9f..41c7acc3 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/ByteBuffer.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/ByteBuffer.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Common.h b/lib/fb/src/main/cpp/include/fb/fbjni/Common.h index 0a6e8521..6025f6d6 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Common.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Common.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - /** @file Common.h * * Defining the stuff that don't deserve headers of their own... diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Context.h b/lib/fb/src/main/cpp/include/fb/fbjni/Context.h index 4505842c..cf5bcb2d 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Context.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Context.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "CoreClasses.h" diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses-inl.h b/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses-inl.h index fd927843..e5c86069 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses-inl.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses-inl.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses.h b/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses.h index 8b2ba839..227e9c79 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/CoreClasses.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once /** @file CoreClasses.h diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Exceptions.h b/lib/fb/src/main/cpp/include/fb/fbjni/Exceptions.h index 4a47619d..fe28154f 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Exceptions.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Exceptions.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - /** * @file Exceptions.h * diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/File.h b/lib/fb/src/main/cpp/include/fb/fbjni/File.h index 9b52183a..857826cc 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/File.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/File.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "CoreClasses.h" diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Hybrid.h b/lib/fb/src/main/cpp/include/fb/fbjni/Hybrid.h index f34ec0f7..8db5b0b9 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Hybrid.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Hybrid.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Iterator-inl.h b/lib/fb/src/main/cpp/include/fb/fbjni/Iterator-inl.h index 8e7083c8..f7c62dcc 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Iterator-inl.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Iterator-inl.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once namespace facebook { diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Iterator.h b/lib/fb/src/main/cpp/include/fb/fbjni/Iterator.h index 1fae26fb..18afea6a 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Iterator.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Iterator.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "CoreClasses.h" diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/JThread.h b/lib/fb/src/main/cpp/include/fb/fbjni/JThread.h index 6bcf9641..7ef4b63b 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/JThread.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/JThread.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "CoreClasses.h" diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Meta-forward.h b/lib/fb/src/main/cpp/include/fb/fbjni/Meta-forward.h index 833acc04..e975f884 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Meta-forward.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Meta-forward.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once namespace facebook { diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Meta-inl.h b/lib/fb/src/main/cpp/include/fb/fbjni/Meta-inl.h index eeac9a01..dfa2c375 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Meta-inl.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Meta-inl.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Meta.h b/lib/fb/src/main/cpp/include/fb/fbjni/Meta.h index ec5eb6ef..418dffbd 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Meta.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Meta.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - /** @file meta.h * * Provides wrappers for meta data such as methods and fields. diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/MetaConvert.h b/lib/fb/src/main/cpp/include/fb/fbjni/MetaConvert.h index 33027c7e..690a6164 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/MetaConvert.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/MetaConvert.h @@ -1,5 +1,9 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/NativeRunnable.h b/lib/fb/src/main/cpp/include/fb/fbjni/NativeRunnable.h index 015c42e5..f459ebf6 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/NativeRunnable.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/NativeRunnable.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "CoreClasses.h" diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators-inl.h b/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators-inl.h index 60ca6531..907ff603 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators-inl.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators-inl.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators.h b/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators.h index 7ccdc5db..e20eef9b 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/ReferenceAllocators.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - /** * @file ReferenceAllocators.h * diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/References-forward.h b/lib/fb/src/main/cpp/include/fb/fbjni/References-forward.h index 78b4f327..eab78de8 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/References-forward.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/References-forward.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "ReferenceAllocators.h" diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/References-inl.h b/lib/fb/src/main/cpp/include/fb/fbjni/References-inl.h index c5049f51..d3329f41 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/References-inl.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/References-inl.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/References.h b/lib/fb/src/main/cpp/include/fb/fbjni/References.h index 884e68d7..00492501 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/References.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/References.h @@ -1,11 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - - /** @file References.h * * Functionality similar to smart pointers, but for references into the VM. Four main reference diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Registration-inl.h b/lib/fb/src/main/cpp/include/fb/fbjni/Registration-inl.h index fc1422e3..030baace 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Registration-inl.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Registration-inl.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/Registration.h b/lib/fb/src/main/cpp/include/fb/fbjni/Registration.h index 74cd7b40..7545840e 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/Registration.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/Registration.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/fbjni/TypeTraits.h b/lib/fb/src/main/cpp/include/fb/fbjni/TypeTraits.h index c38a90b3..95c146fc 100644 --- a/lib/fb/src/main/cpp/include/fb/fbjni/TypeTraits.h +++ b/lib/fb/src/main/cpp/include/fb/fbjni/TypeTraits.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/fb/lyra.h b/lib/fb/src/main/cpp/include/fb/lyra.h index c60ff27b..0d199e6e 100644 --- a/lib/fb/src/main/cpp/include/fb/lyra.h +++ b/lib/fb/src/main/cpp/include/fb/lyra.h @@ -1,5 +1,9 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/include/fb/noncopyable.h b/lib/fb/src/main/cpp/include/fb/noncopyable.h index 283f0fac..ec00ada5 100644 --- a/lib/fb/src/main/cpp/include/fb/noncopyable.h +++ b/lib/fb/src/main/cpp/include/fb/noncopyable.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once namespace facebook { diff --git a/lib/fb/src/main/cpp/include/fb/nonmovable.h b/lib/fb/src/main/cpp/include/fb/nonmovable.h index 819f7193..9b39b8c6 100644 --- a/lib/fb/src/main/cpp/include/fb/nonmovable.h +++ b/lib/fb/src/main/cpp/include/fb/nonmovable.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once namespace facebook { diff --git a/lib/fb/src/main/cpp/include/fb/visibility.h b/lib/fb/src/main/cpp/include/fb/visibility.h index 098d5ddc..310fbe11 100644 --- a/lib/fb/src/main/cpp/include/fb/visibility.h +++ b/lib/fb/src/main/cpp/include/fb/visibility.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once #define FBEXPORT __attribute__((visibility("default"))) diff --git a/lib/fb/src/main/cpp/include/jni/Countable.h b/lib/fb/src/main/cpp/include/jni/Countable.h index 8a8d3206..b2708aae 100644 --- a/lib/fb/src/main/cpp/include/jni/Countable.h +++ b/lib/fb/src/main/cpp/include/jni/Countable.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/jni/GlobalReference.h b/lib/fb/src/main/cpp/include/jni/GlobalReference.h index 15624bb5..9ebdfcd5 100644 --- a/lib/fb/src/main/cpp/include/jni/GlobalReference.h +++ b/lib/fb/src/main/cpp/include/jni/GlobalReference.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/jni/LocalReference.h b/lib/fb/src/main/cpp/include/jni/LocalReference.h index 03aad078..b565ee74 100644 --- a/lib/fb/src/main/cpp/include/jni/LocalReference.h +++ b/lib/fb/src/main/cpp/include/jni/LocalReference.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/jni/LocalString.h b/lib/fb/src/main/cpp/include/jni/LocalString.h index 19edabf5..34316531 100644 --- a/lib/fb/src/main/cpp/include/jni/LocalString.h +++ b/lib/fb/src/main/cpp/include/jni/LocalString.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/jni/Registration.h b/lib/fb/src/main/cpp/include/jni/Registration.h index 1b19418e..553ddaf8 100644 --- a/lib/fb/src/main/cpp/include/jni/Registration.h +++ b/lib/fb/src/main/cpp/include/jni/Registration.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/jni/WeakReference.h b/lib/fb/src/main/cpp/include/jni/WeakReference.h index 7b1df7c8..70630b10 100644 --- a/lib/fb/src/main/cpp/include/jni/WeakReference.h +++ b/lib/fb/src/main/cpp/include/jni/WeakReference.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/include/jni/jni_helpers.h b/lib/fb/src/main/cpp/include/jni/jni_helpers.h index cabf6572..cf6504a4 100644 --- a/lib/fb/src/main/cpp/include/jni/jni_helpers.h +++ b/lib/fb/src/main/cpp/include/jni/jni_helpers.h @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/jni/ByteBuffer.cpp b/lib/fb/src/main/cpp/jni/ByteBuffer.cpp index dce234fd..9d7cbda9 100644 --- a/lib/fb/src/main/cpp/jni/ByteBuffer.cpp +++ b/lib/fb/src/main/cpp/jni/ByteBuffer.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/lib/fb/src/main/cpp/jni/Countable.cpp b/lib/fb/src/main/cpp/jni/Countable.cpp index 1d4bfc55..bbb6f23d 100644 --- a/lib/fb/src/main/cpp/jni/Countable.cpp +++ b/lib/fb/src/main/cpp/jni/Countable.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/jni/Environment.cpp b/lib/fb/src/main/cpp/jni/Environment.cpp index b9523df3..8d37cb52 100644 --- a/lib/fb/src/main/cpp/jni/Environment.cpp +++ b/lib/fb/src/main/cpp/jni/Environment.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/jni/Exceptions.cpp b/lib/fb/src/main/cpp/jni/Exceptions.cpp index 754a2d4d..8688dfbf 100644 --- a/lib/fb/src/main/cpp/jni/Exceptions.cpp +++ b/lib/fb/src/main/cpp/jni/Exceptions.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/lib/fb/src/main/cpp/jni/Hybrid.cpp b/lib/fb/src/main/cpp/jni/Hybrid.cpp index 2956bba2..c04560a5 100644 --- a/lib/fb/src/main/cpp/jni/Hybrid.cpp +++ b/lib/fb/src/main/cpp/jni/Hybrid.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include "fb/fbjni.h" diff --git a/lib/fb/src/main/cpp/jni/LocalString.cpp b/lib/fb/src/main/cpp/jni/LocalString.cpp index 073ef32f..9233ec02 100644 --- a/lib/fb/src/main/cpp/jni/LocalString.cpp +++ b/lib/fb/src/main/cpp/jni/LocalString.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/jni/OnLoad.cpp b/lib/fb/src/main/cpp/jni/OnLoad.cpp index ebd8c879..a95393f8 100644 --- a/lib/fb/src/main/cpp/jni/OnLoad.cpp +++ b/lib/fb/src/main/cpp/jni/OnLoad.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/jni/References.cpp b/lib/fb/src/main/cpp/jni/References.cpp index d41010f8..71284b0e 100644 --- a/lib/fb/src/main/cpp/jni/References.cpp +++ b/lib/fb/src/main/cpp/jni/References.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include namespace facebook { diff --git a/lib/fb/src/main/cpp/jni/WeakReference.cpp b/lib/fb/src/main/cpp/jni/WeakReference.cpp index bdf3f24d..5552a763 100644 --- a/lib/fb/src/main/cpp/jni/WeakReference.cpp +++ b/lib/fb/src/main/cpp/jni/WeakReference.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/lib/fb/src/main/cpp/jni/fbjni.cpp b/lib/fb/src/main/cpp/jni/fbjni.cpp index 51adf9a8..c556fabb 100644 --- a/lib/fb/src/main/cpp/jni/fbjni.cpp +++ b/lib/fb/src/main/cpp/jni/fbjni.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/lib/fb/src/main/cpp/jni/jni_helpers.cpp b/lib/fb/src/main/cpp/jni/jni_helpers.cpp index 86dbbc57..c45217bf 100644 --- a/lib/fb/src/main/cpp/jni/jni_helpers.cpp +++ b/lib/fb/src/main/cpp/jni/jni_helpers.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/log.cpp b/lib/fb/src/main/cpp/log.cpp index 7d2a70df..8d22bcbc 100644 --- a/lib/fb/src/main/cpp/log.cpp +++ b/lib/fb/src/main/cpp/log.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/lib/fb/src/main/cpp/lyra/lyra.cpp b/lib/fb/src/main/cpp/lyra/lyra.cpp index f915ecef..4d125da7 100644 --- a/lib/fb/src/main/cpp/lyra/lyra.cpp +++ b/lib/fb/src/main/cpp/lyra/lyra.cpp @@ -1,5 +1,9 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/lib/fb/src/main/cpp/onload.cpp b/lib/fb/src/main/cpp/onload.cpp index 158d8832..c451bcba 100644 --- a/lib/fb/src/main/cpp/onload.cpp +++ b/lib/fb/src/main/cpp/onload.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #ifndef DISABLE_CPUCAP #include diff --git a/lib/jni/jni.h b/lib/jni/jni.h index 34d46448..91b28ab4 100644 --- a/lib/jni/jni.h +++ b/lib/jni/jni.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once #ifdef __ANDROID__ diff --git a/tests/YGAbsolutePositionTest.cpp b/tests/YGAbsolutePositionTest.cpp index f9ec49a3..1faf554f 100644 --- a/tests/YGAbsolutePositionTest.cpp +++ b/tests/YGAbsolutePositionTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGAbsolutePositionTest.html #include diff --git a/tests/YGAlignBaselineTest.cpp b/tests/YGAlignBaselineTest.cpp index 0ede52bd..eae27908 100644 --- a/tests/YGAlignBaselineTest.cpp +++ b/tests/YGAlignBaselineTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/tests/YGAlignContentTest.cpp b/tests/YGAlignContentTest.cpp index 1a46ad50..af6fe529 100644 --- a/tests/YGAlignContentTest.cpp +++ b/tests/YGAlignContentTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignContentTest.html #include diff --git a/tests/YGAlignItemsTest.cpp b/tests/YGAlignItemsTest.cpp index 0b4ddba1..345b6a29 100644 --- a/tests/YGAlignItemsTest.cpp +++ b/tests/YGAlignItemsTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignItemsTest.html diff --git a/tests/YGAlignSelfTest.cpp b/tests/YGAlignSelfTest.cpp index eec2bae4..8bcacff7 100644 --- a/tests/YGAlignSelfTest.cpp +++ b/tests/YGAlignSelfTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignSelfTest.html #include diff --git a/tests/YGAndroidNewsFeed.cpp b/tests/YGAndroidNewsFeed.cpp index 9496bf71..db3753d6 100644 --- a/tests/YGAndroidNewsFeed.cpp +++ b/tests/YGAndroidNewsFeed.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGAndroidNewsFeed.html #include diff --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp index 8f2dc8e3..9d99569b 100644 --- a/tests/YGAspectRatioTest.cpp +++ b/tests/YGAspectRatioTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/tests/YGBaselineFuncTest.cpp b/tests/YGBaselineFuncTest.cpp index 362904cb..97d86050 100644 --- a/tests/YGBaselineFuncTest.cpp +++ b/tests/YGBaselineFuncTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/tests/YGBorderTest.cpp b/tests/YGBorderTest.cpp index 540c448a..75571ccc 100644 --- a/tests/YGBorderTest.cpp +++ b/tests/YGBorderTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGBorderTest.html #include diff --git a/tests/YGComputedMarginTest.cpp b/tests/YGComputedMarginTest.cpp index a3d1f442..8468dd6b 100644 --- a/tests/YGComputedMarginTest.cpp +++ b/tests/YGComputedMarginTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/tests/YGComputedPaddingTest.cpp b/tests/YGComputedPaddingTest.cpp index fad7ce1b..2a22607f 100644 --- a/tests/YGComputedPaddingTest.cpp +++ b/tests/YGComputedPaddingTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/tests/YGDefaultValuesTest.cpp b/tests/YGDefaultValuesTest.cpp index 82aa7323..4d4d2c5c 100644 --- a/tests/YGDefaultValuesTest.cpp +++ b/tests/YGDefaultValuesTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGDimensionTest.cpp b/tests/YGDimensionTest.cpp index 04a14846..9baf4006 100644 --- a/tests/YGDimensionTest.cpp +++ b/tests/YGDimensionTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGDimensionTest.html #include diff --git a/tests/YGDirtiedTest.cpp b/tests/YGDirtiedTest.cpp index f68c1450..5fb291be 100644 --- a/tests/YGDirtiedTest.cpp +++ b/tests/YGDirtiedTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGDirtyMarkingTest.cpp b/tests/YGDirtyMarkingTest.cpp index 709b8904..984e7228 100644 --- a/tests/YGDirtyMarkingTest.cpp +++ b/tests/YGDirtyMarkingTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGDisplayTest.cpp b/tests/YGDisplayTest.cpp index 46e3ed3e..52ff9cc8 100644 --- a/tests/YGDisplayTest.cpp +++ b/tests/YGDisplayTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html #include diff --git a/tests/YGEdgeTest.cpp b/tests/YGEdgeTest.cpp index f4d92d7c..fb907df6 100644 --- a/tests/YGEdgeTest.cpp +++ b/tests/YGEdgeTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGFlexDirectionTest.cpp b/tests/YGFlexDirectionTest.cpp index 7bd003df..92bc450d 100644 --- a/tests/YGFlexDirectionTest.cpp +++ b/tests/YGFlexDirectionTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexDirectionTest.html #include diff --git a/tests/YGFlexTest.cpp b/tests/YGFlexTest.cpp index 67cc2bbc..5ba49f43 100644 --- a/tests/YGFlexTest.cpp +++ b/tests/YGFlexTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ // @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexTest.html diff --git a/tests/YGFlexWrapTest.cpp b/tests/YGFlexWrapTest.cpp index abe241a1..12d4e353 100644 --- a/tests/YGFlexWrapTest.cpp +++ b/tests/YGFlexWrapTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexWrapTest.html #include diff --git a/tests/YGHadOverflowTest.cpp b/tests/YGHadOverflowTest.cpp index 47dc2809..d0f8a332 100644 --- a/tests/YGHadOverflowTest.cpp +++ b/tests/YGHadOverflowTest.cpp @@ -1,5 +1,9 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/tests/YGInfiniteHeightTest.cpp b/tests/YGInfiniteHeightTest.cpp index 3e189caf..6a0cf307 100644 --- a/tests/YGInfiniteHeightTest.cpp +++ b/tests/YGInfiniteHeightTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGJustifyContentTest.cpp b/tests/YGJustifyContentTest.cpp index 7ed1c72b..34deb973 100644 --- a/tests/YGJustifyContentTest.cpp +++ b/tests/YGJustifyContentTest.cpp @@ -1,8 +1,8 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ // @Generated by gentest/gentest.rb from // gentest/fixtures/YGJustifyContentTest.html diff --git a/tests/YGLayoutDiffingTest.cpp b/tests/YGLayoutDiffingTest.cpp index cb24a295..96361d16 100644 --- a/tests/YGLayoutDiffingTest.cpp +++ b/tests/YGLayoutDiffingTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/tests/YGLoggerTest.cpp b/tests/YGLoggerTest.cpp index ccf0ad2b..3cf1095a 100644 --- a/tests/YGLoggerTest.cpp +++ b/tests/YGLoggerTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/tests/YGMarginTest.cpp b/tests/YGMarginTest.cpp index ba1b3cbc..6eb01a50 100644 --- a/tests/YGMarginTest.cpp +++ b/tests/YGMarginTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGMarginTest.html #include diff --git a/tests/YGMeasureCacheTest.cpp b/tests/YGMeasureCacheTest.cpp index bd56172f..dfb7d2e9 100644 --- a/tests/YGMeasureCacheTest.cpp +++ b/tests/YGMeasureCacheTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/tests/YGMeasureModeTest.cpp b/tests/YGMeasureModeTest.cpp index f05ddd89..9dd0416e 100644 --- a/tests/YGMeasureModeTest.cpp +++ b/tests/YGMeasureModeTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/tests/YGMeasureTest.cpp b/tests/YGMeasureTest.cpp index 93db13b1..a330523d 100644 --- a/tests/YGMeasureTest.cpp +++ b/tests/YGMeasureTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/tests/YGMinMaxDimensionTest.cpp b/tests/YGMinMaxDimensionTest.cpp index d38148be..dd16e5f9 100644 --- a/tests/YGMinMaxDimensionTest.cpp +++ b/tests/YGMinMaxDimensionTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGMinMaxDimensionTest.html #include diff --git a/tests/YGNodeChildTest.cpp b/tests/YGNodeChildTest.cpp index c159d9e4..b5aa6cfe 100644 --- a/tests/YGNodeChildTest.cpp +++ b/tests/YGNodeChildTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGPaddingTest.cpp b/tests/YGPaddingTest.cpp index 1a961c9c..c6f431b8 100644 --- a/tests/YGPaddingTest.cpp +++ b/tests/YGPaddingTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ // @Generated by gentest/gentest.rb from gentest/fixtures/YGPaddingTest.html diff --git a/tests/YGPercentageTest.cpp b/tests/YGPercentageTest.cpp index 660af91f..93776413 100644 --- a/tests/YGPercentageTest.cpp +++ b/tests/YGPercentageTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGPercentageTest.html #include diff --git a/tests/YGPersistenceTest.cpp b/tests/YGPersistenceTest.cpp index 43101fc5..c9d94e89 100644 --- a/tests/YGPersistenceTest.cpp +++ b/tests/YGPersistenceTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGRelayoutTest.cpp b/tests/YGRelayoutTest.cpp index 990e948d..fdbe3608 100644 --- a/tests/YGRelayoutTest.cpp +++ b/tests/YGRelayoutTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGRoundingFunctionTest.cpp b/tests/YGRoundingFunctionTest.cpp index fa16b60e..672e8afd 100644 --- a/tests/YGRoundingFunctionTest.cpp +++ b/tests/YGRoundingFunctionTest.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/tests/YGRoundingMeasureFuncTest.cpp b/tests/YGRoundingMeasureFuncTest.cpp index db9ea701..5cf2120f 100644 --- a/tests/YGRoundingMeasureFuncTest.cpp +++ b/tests/YGRoundingMeasureFuncTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/tests/YGRoundingTest.cpp b/tests/YGRoundingTest.cpp index ee91c6cd..84f3da73 100644 --- a/tests/YGRoundingTest.cpp +++ b/tests/YGRoundingTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGRoundingTest.html #include diff --git a/tests/YGSizeOverflowTest.cpp b/tests/YGSizeOverflowTest.cpp index 06f5be17..73b35b72 100644 --- a/tests/YGSizeOverflowTest.cpp +++ b/tests/YGSizeOverflowTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGSizeOverflowTest.html #include diff --git a/tests/YGStyleTest.cpp b/tests/YGStyleTest.cpp index f36ed312..c5722708 100644 --- a/tests/YGStyleTest.cpp +++ b/tests/YGStyleTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/tests/YGTraversalTest.cpp b/tests/YGTraversalTest.cpp index 471919c8..c77ba3f4 100644 --- a/tests/YGTraversalTest.cpp +++ b/tests/YGTraversalTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGTreeMutationTest.cpp b/tests/YGTreeMutationTest.cpp index 70c9a970..a7a625cd 100644 --- a/tests/YGTreeMutationTest.cpp +++ b/tests/YGTreeMutationTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/tests/YGZeroOutLayoutRecursivlyTest.cpp b/tests/YGZeroOutLayoutRecursivlyTest.cpp index 735fa62d..052f60d5 100644 --- a/tests/YGZeroOutLayoutRecursivlyTest.cpp +++ b/tests/YGZeroOutLayoutRecursivlyTest.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include #include diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 5322642f..74cc38c9 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ #include "Utils.h" diff --git a/yoga/Utils.h b/yoga/Utils.h index db257ae5..d578511c 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "YGNode.h" #include "Yoga-internal.h" diff --git a/yoga/YGConfig.cpp b/yoga/YGConfig.cpp index e0edd3f7..2f73dd9a 100644 --- a/yoga/YGConfig.cpp +++ b/yoga/YGConfig.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ #include "YGConfig.h" diff --git a/yoga/YGConfig.h b/yoga/YGConfig.h index b5f3c5fd..c9b871fe 100644 --- a/yoga/YGConfig.h +++ b/yoga/YGConfig.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 "YGMarker.h" diff --git a/yoga/YGEnums.cpp b/yoga/YGEnums.cpp index 5f8ef9af..e2518176 100644 --- a/yoga/YGEnums.cpp +++ b/yoga/YGEnums.cpp @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include "YGEnums.h" const char *YGAlignToString(const YGAlign value){ diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index db555281..da223051 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "YGMacros.h" diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp index c7ade6a2..d023dccb 100644 --- a/yoga/YGFloatOptional.cpp +++ b/yoga/YGFloatOptional.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ #include "YGFloatOptional.h" #include diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 2578b9dd..07fbb64b 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/yoga/YGLayout.cpp b/yoga/YGLayout.cpp index 0f362f88..6f55d862 100644 --- a/yoga/YGLayout.cpp +++ b/yoga/YGLayout.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ #include "YGLayout.h" #include "Utils.h" diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h index 812ed6bd..2a0215d3 100644 --- a/yoga/YGLayout.h +++ b/yoga/YGLayout.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 "YGFloatOptional.h" diff --git a/yoga/YGMacros.h b/yoga/YGMacros.h index 0aafdca3..7da8a870 100644 --- a/yoga/YGMacros.h +++ b/yoga/YGMacros.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #pragma once #ifdef __cplusplus diff --git a/yoga/YGMarker.h b/yoga/YGMarker.h index 00c582ab..3eb665fe 100644 --- a/yoga/YGMarker.h +++ b/yoga/YGMarker.h @@ -1,10 +1,9 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 "YGMacros.h" diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 189a3df1..1694692c 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ #include "YGNode.h" #include diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 678926d3..719eb2ea 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index cd11bec6..541a6fef 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -1,10 +1,9 @@ -/* +/** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ - #include "YGNodePrint.h" #include #include "YGEnums.h" diff --git a/yoga/YGNodePrint.h b/yoga/YGNodePrint.h index a4f24cb5..9d36ba8d 100644 --- a/yoga/YGNodePrint.h +++ b/yoga/YGNodePrint.h @@ -1,8 +1,8 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. + * 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 diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp index 46a65b28..bc90463e 100644 --- a/yoga/YGStyle.cpp +++ b/yoga/YGStyle.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ #include "YGStyle.h" diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index 04a74545..c3a01d44 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 "YGFloatOptional.h" diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 0e02646c..1e9a1aaf 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 463107ee..6abfb7d3 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ #include "Yoga.h" #include diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 04e0bf1d..96e71dc7 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -1,9 +1,8 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its 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 -- 2.50.1.windows.1 From 0962c5220c866c6e3be157d79d3bc7844cc24ced Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:07 -0800 Subject: [PATCH 09/53] Roll back `-ffast-math` Summary: @public `-ffast-math` does not have measurable performance benefits. By using `NaN` for *undefined* values again, we can squeeze `YGFloatOptional` into 32 bits. This will also enable us to store `YGValue` (or a variant of it) in 32 bits. Reviewed By: SidharthGuglani Differential Revision: D13119110 fbshipit-source-id: 4e6964240bf74ebc22d8783107b89d536a1a0842 --- csharp/Facebook.Yoga/YogaConstants.cs | 23 +++-------------- java/com/facebook/yoga/YogaConstants.java | 30 +++++------------------ tools/build_defs/oss/yoga_defs.bzl | 1 - yoga/Utils.h | 14 +++-------- yoga/Yoga-internal.h | 10 +------- yoga/Yoga.cpp | 5 +--- yoga/Yoga.h | 15 ++++++------ 7 files changed, 21 insertions(+), 77 deletions(-) diff --git a/csharp/Facebook.Yoga/YogaConstants.cs b/csharp/Facebook.Yoga/YogaConstants.cs index a715b43c..9e05cca3 100644 --- a/csharp/Facebook.Yoga/YogaConstants.cs +++ b/csharp/Facebook.Yoga/YogaConstants.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -9,28 +9,11 @@ namespace Facebook.Yoga { public static class YogaConstants { - /** - * Large positive number signifies that the property(float) is undefined. Earlier we used to have - * YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as - * it assumes all floating-point calculation involve and result into finite numbers. For more - * information regarding -ffast-math compiler flag in clang, have a look at - * https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math - */ - public const float Undefined = 10E20F; + public const float Undefined = float.NaN; public static bool IsUndefined(float value) { - // Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN, - // the benefit of which - // was that if NAN is involved in any mathematical expression the result was NAN. But since we - // want to have `-ffast-math` - // flag being used by compiler which assumes that the floating point values are not NAN and Inf, - // we represent YGUndefined as 10.1E20. - // But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would - // change. - // So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it - // is undefined. - return value >= 10E8F || value <= -10E8; + return float.IsNaN(value); } public static bool IsUndefined(YogaValue value) diff --git a/java/com/facebook/yoga/YogaConstants.java b/java/com/facebook/yoga/YogaConstants.java index 61e212ef..b04a7e53 100644 --- a/java/com/facebook/yoga/YogaConstants.java +++ b/java/com/facebook/yoga/YogaConstants.java @@ -1,35 +1,17 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ package com.facebook.yoga; public class YogaConstants { - /** - * Large positive number signifies that the property(float) is undefined. Earlier we used to have - * YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as - * it assumes all floating-point calculation involve and result into finite numbers. For more - * information regarding -ffast-math compiler flag in clang, have a look at - * https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math - */ - public static final float UNDEFINED = (float) (10E20); + public static final float UNDEFINED = Float.NaN; public static boolean isUndefined(float value) { - // Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN, - // the benefit of which - // was that if NAN is involved in any mathematical expression the result was NAN. But since we - // want to have `-ffast-math` - // flag being used by compiler which assumes that the floating point values are not NAN and Inf, - // we represent YGUndefined as 10.1E20. - // But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would - // change. - // So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it - // is undefined. - return (Float.compare(value, (float) 10E8) >= 0 || Float.compare(value, (float) -10E8) <= 0); + return Float.compare(value, UNDEFINED) == 0; } public static boolean isUndefined(YogaValue value) { diff --git a/tools/build_defs/oss/yoga_defs.bzl b/tools/build_defs/oss/yoga_defs.bzl index 7eca7b9b..5a5872fe 100644 --- a/tools/build_defs/oss/yoga_defs.bzl +++ b/tools/build_defs/oss/yoga_defs.bzl @@ -58,7 +58,6 @@ BASE_COMPILER_FLAGS = [ "-Wall", "-Werror", "-O3", - "-ffast-math", ] LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [ diff --git a/yoga/Utils.h b/yoga/Utils.h index d578511c..d007ff54 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -57,22 +57,12 @@ bool YGValueEqual(const YGValue a, const YGValue b); // difference between two floats is less than 0.0001f or both are undefined. bool YGFloatsEqual(const float a, const float b); -// We need custom max function, since we want that, if one argument is -// YGUndefined then the max funtion should return the other argument as the max -// value. We wouldn't have needed a custom max function if YGUndefined was NAN -// as fmax has the same behaviour, but with NAN we cannot use `-ffast-math` -// compiler flag. float YGFloatMax(const float a, const float b); YGFloatOptional YGFloatOptionalMax( const YGFloatOptional& op1, const YGFloatOptional& op2); -// We need custom min function, since we want that, if one argument is -// YGUndefined then the min funtion should return the other argument as the min -// value. We wouldn't have needed a custom min function if YGUndefined was NAN -// as fmin has the same behaviour, but with NAN we cannot use `-ffast-math` -// compiler flag. float YGFloatMin(const float a, const float b); // This custom float comparision function compares the array of float with @@ -106,7 +96,9 @@ inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { flexDirection == YGFlexDirectionRowReverse; } -inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) { +inline YGFloatOptional YGResolveValue( + const YGValue value, + const float ownerSize) { switch (value.unit) { case YGUnitUndefined: case YGUnitAuto: diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 1e9a1aaf..ef5e5d8c 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -27,15 +27,7 @@ namespace facebook { namespace yoga { inline bool isUndefined(float value) { - // Value of a float in the case of it being not defined is 10.1E20. Earlier - // it used to be NAN, the benefit of which was that if NAN is involved in any - // mathematical expression the result was NAN. But since we want to have - // `-ffast-math` flag being used by compiler which assumes that the floating - // point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But - // now if YGUndefined is involved in any mathematical operations this - // value(10.1E20) would change. So the following check makes sure that if the - // value is outside a range (-10E8, 10E8) then it is undefined. - return value >= 10E8 || value <= -10E8; + return std::isnan(value); } } // namespace yoga diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 6abfb7d3..d5fc12ef 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -18,10 +18,7 @@ /* define fmaxf if < VC12 */ #if _MSC_VER < 1800 __forceinline const float fmaxf(const float a, const float b) { - if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { - return (a > b) ? a : b; - } - return YGFloatIsUndefined(a) ? b : a; + return (a > b) ? a : b; } #endif #endif diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 96e71dc7..61aae0fe 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -17,14 +17,13 @@ #include #endif -/** Large positive number signifies that the property(float) is undefined. - *Earlier we used to have YGundefined as NAN, but the downside of this is that - *we can't use -ffast-math compiler flag as it assumes all floating-point - *calculation involve and result into finite numbers. For more information - *regarding -ffast-math compiler flag in clang, have a look at - *https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math - **/ -#define YGUndefined 10E20F +// Not defined in MSVC++ +#ifndef NAN +static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; +#define NAN (*(const float*)__nan) +#endif + +#define YGUndefined NAN #include "YGEnums.h" #include "YGMacros.h" -- 2.50.1.windows.1 From d19da9e528842871e4610066b325c8cd6af0a160 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:08 -0800 Subject: [PATCH 10/53] Move out `YGValue` Summary: @public Creates a single header file for `YGValue`. This is in preparation of a more compact representation of `YGValue` within `YGStyle`. Also fixes the incorrect definition of NAN. Reviewed By: SidharthGuglani Differential Revision: D13172444 fbshipit-source-id: 4250dbcf8fe15ec3ecdee3913360a73bab633ce3 --- yoga/YGValue.cpp | 29 +++++++++++++++++++++++++++++ yoga/YGValue.h | 40 ++++++++++++++++++++++++++++++++++++++++ yoga/Yoga.cpp | 17 ----------------- yoga/Yoga.h | 28 +--------------------------- 4 files changed, 70 insertions(+), 44 deletions(-) create mode 100644 yoga/YGValue.cpp create mode 100644 yoga/YGValue.h diff --git a/yoga/YGValue.cpp b/yoga/YGValue.cpp new file mode 100644 index 00000000..4bfe083d --- /dev/null +++ b/yoga/YGValue.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + */ +#include "YGValue.h" + +const YGValue YGValueZero = {0, YGUnitPoint}; +const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; +const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; + +bool operator==(const YGValue& lhs, const YGValue& rhs) { + if (lhs.unit != rhs.unit) { + return false; + } + + switch (lhs.unit) { + case YGUnitUndefined: + case YGUnitAuto: + return true; + default: + return lhs.value == rhs.value; + } +} + +bool operator!=(const YGValue& lhs, const YGValue& rhs) { + return !(lhs == rhs); +} diff --git a/yoga/YGValue.h b/yoga/YGValue.h new file mode 100644 index 00000000..803b8e78 --- /dev/null +++ b/yoga/YGValue.h @@ -0,0 +1,40 @@ +/** + * Copyright (c) Facebook, Inc. and its 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 "YGEnums.h" +#include "YGMacros.h" + +YG_EXTERN_C_BEGIN + +// Not defined in MSVC++ +#ifndef NAN +static const uint32_t __nan = 0x7fc00000; +#define NAN (*(const float*)__nan) +#endif + +#define YGUndefined NAN + +typedef struct YGValue { + float value; + YGUnit unit; +} YGValue; + +extern const YGValue YGValueAuto; +extern const YGValue YGValueUndefined; +extern const YGValue YGValueZero; + +YG_EXTERN_C_END + +#ifdef __cplusplus + +bool operator==(const YGValue& lhs, const YGValue& rhs); + +bool operator!=(const YGValue& lhs, const YGValue& rhs); + +#endif diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index d5fc12ef..246e0f41 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -39,23 +39,6 @@ static int YGDefaultLog( va_list args); #endif -const YGValue YGValueZero = {0, YGUnitPoint}; -const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; -const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; - -bool operator==(const YGValue& lhs, const YGValue& rhs) { - if ((lhs.unit == YGUnitUndefined && rhs.unit == YGUnitUndefined) || - (lhs.unit == YGUnitAuto && rhs.unit == YGUnitAuto)) { - return true; - } - - return lhs.unit == rhs.unit && lhs.value == rhs.value; -} - -bool operator!=(const YGValue& lhs, const YGValue& rhs) { - return !(lhs == rhs); -} - #ifdef ANDROID #include static int YGAndroidLog( diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 61aae0fe..787af6df 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -17,16 +17,9 @@ #include #endif -// Not defined in MSVC++ -#ifndef NAN -static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; -#define NAN (*(const float*)__nan) -#endif - -#define YGUndefined NAN - #include "YGEnums.h" #include "YGMacros.h" +#include "YGValue.h" YG_EXTERN_C_BEGIN @@ -35,25 +28,6 @@ typedef struct YGSize { float height; } YGSize; -typedef struct YGValue { - float value; - YGUnit unit; -} YGValue; - -extern const YGValue YGValueUndefined; -extern const YGValue YGValueAuto; - -#ifdef __cplusplus - -YG_EXTERN_C_END - -extern bool operator==(const YGValue& lhs, const YGValue& rhs); -extern bool operator!=(const YGValue& lhs, const YGValue& rhs); - -YG_EXTERN_C_BEGIN - -#endif - typedef struct YGConfig* YGConfigRef; typedef struct YGNode* YGNodeRef; -- 2.50.1.windows.1 From ed5c5a799f8111f1e55507158d68641133184771 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:08 -0800 Subject: [PATCH 11/53] Make equality operator for `YGValue` inlineable Summary: @public Makes `operator==` for `YGValue` an inline function. Reviewed By: SidharthGuglani Differential Revision: D13189356 fbshipit-source-id: 7fe61035acf635e22ebb1a1071925d6b3dad0616 --- yoga/YGValue.cpp | 18 ------------------ yoga/YGValue.h | 20 ++++++++++++++++++-- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/yoga/YGValue.cpp b/yoga/YGValue.cpp index 4bfe083d..fcdd0c69 100644 --- a/yoga/YGValue.cpp +++ b/yoga/YGValue.cpp @@ -9,21 +9,3 @@ const YGValue YGValueZero = {0, YGUnitPoint}; const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; - -bool operator==(const YGValue& lhs, const YGValue& rhs) { - if (lhs.unit != rhs.unit) { - return false; - } - - switch (lhs.unit) { - case YGUnitUndefined: - case YGUnitAuto: - return true; - default: - return lhs.value == rhs.value; - } -} - -bool operator!=(const YGValue& lhs, const YGValue& rhs) { - return !(lhs == rhs); -} diff --git a/yoga/YGValue.h b/yoga/YGValue.h index 803b8e78..4e43f7b2 100644 --- a/yoga/YGValue.h +++ b/yoga/YGValue.h @@ -33,8 +33,24 @@ YG_EXTERN_C_END #ifdef __cplusplus -bool operator==(const YGValue& lhs, const YGValue& rhs); +inline bool operator==(const YGValue& lhs, const YGValue& rhs) { + if (lhs.unit != rhs.unit) { + return false; + } -bool operator!=(const YGValue& lhs, const YGValue& rhs); + switch (lhs.unit) { + case YGUnitUndefined: + case YGUnitAuto: + return true; + case YGUnitPoint: + case YGUnitPercent: + default: + return lhs.value == rhs.value; + } +} + +inline bool operator!=(const YGValue& lhs, const YGValue& rhs) { + return !(lhs == rhs); +} #endif -- 2.50.1.windows.1 From ed3b54b603cc3bf3483812823e06fa166eb1cf71 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:08 -0800 Subject: [PATCH 12/53] Store `YGFloatOptional` in 32 bits Summary: @public After removing `-ffast-math`, `NaN` can again be used to represent `undefined`. That allows us to remove the additional flag from `YGFloatOptional`, and reduce memory usage. Reviewed By: SidharthGuglani Differential Revision: D13209157 fbshipit-source-id: 21b83c837a78f924a4ec23a9236ca2440b3c8606 --- tests/YGFloatOptionalTest.cpp | 163 ++++++++++++++++++++++++++++++++++ yoga/YGFloatOptional.cpp | 53 +++-------- yoga/YGFloatOptional.h | 32 +++---- yoga/YGNode.cpp | 2 +- 4 files changed, 192 insertions(+), 58 deletions(-) create mode 100644 tests/YGFloatOptionalTest.cpp diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp new file mode 100644 index 00000000..2096e5fd --- /dev/null +++ b/tests/YGFloatOptionalTest.cpp @@ -0,0 +1,163 @@ +/** + * Copyright (c) Facebook, Inc. and its 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 + +constexpr auto empty = YGFloatOptional{}; +constexpr auto zero = YGFloatOptional{0.0f}; +constexpr auto one = YGFloatOptional{1.0f}; +constexpr auto positive = YGFloatOptional{1234.5f}; +constexpr auto negative = YGFloatOptional{-9876.5f}; + +TEST(YGFloatOptional, value) { + ASSERT_EQ(zero.getValue(), 0.0f); + ASSERT_EQ(positive.getValue(), 1234.5f); + ASSERT_EQ(negative.getValue(), -9876.5f); + + ASSERT_TRUE(empty.isUndefined()); + ASSERT_FALSE(zero.isUndefined()); + ASSERT_FALSE(negative.isUndefined()); +} + +TEST(YGFloatOptional, equality) { + ASSERT_TRUE(empty == empty); + ASSERT_TRUE(empty == YGUndefined); + ASSERT_FALSE(empty == zero); + ASSERT_FALSE(empty == negative); + ASSERT_FALSE(empty == 12.3f); + + ASSERT_TRUE(zero == zero); + ASSERT_TRUE(zero == 0.0f); + ASSERT_FALSE(zero == positive); + ASSERT_FALSE(zero == -5555.5f); + + ASSERT_TRUE(one == one); + ASSERT_TRUE(one == 1.0f); + ASSERT_FALSE(one == positive); + + ASSERT_TRUE(negative == negative); + ASSERT_TRUE(negative == negative.getValue()); + ASSERT_FALSE(negative == zero); +} + +TEST(YGFloatOptional, inequality) { + ASSERT_FALSE(empty != empty); + ASSERT_FALSE(empty != YGUndefined); + ASSERT_TRUE(empty != zero); + ASSERT_TRUE(empty != negative); + ASSERT_TRUE(empty != 12.3f); + + ASSERT_FALSE(zero != zero); + ASSERT_FALSE(zero != 0.0f); + ASSERT_TRUE(zero != positive); + ASSERT_TRUE(zero != -5555.5f); + + ASSERT_FALSE(one != one); + ASSERT_FALSE(one != 1.0f); + ASSERT_TRUE(one != positive); + + ASSERT_FALSE(negative != negative); + ASSERT_FALSE(negative != negative.getValue()); + ASSERT_TRUE(negative != zero); +} + +TEST(YGFloatOptional, greater) { + ASSERT_FALSE(empty > empty); + ASSERT_FALSE(empty > zero); + ASSERT_FALSE(empty > one); + ASSERT_FALSE(empty > positive); + ASSERT_FALSE(empty > negative); + + ASSERT_TRUE(zero > negative); + ASSERT_FALSE(zero > zero); + ASSERT_FALSE(zero > positive); + ASSERT_FALSE(zero > one); + + ASSERT_TRUE(one > negative); + ASSERT_TRUE(one > zero); + ASSERT_FALSE(one > empty); + ASSERT_FALSE(one > positive); + + ASSERT_TRUE(negative > YGFloatOptional{-INFINITY}); + ASSERT_FALSE(negative > empty); +} + +TEST(YGFloatOptional, lower) { + ASSERT_FALSE(empty < empty); + ASSERT_FALSE(empty < zero); + ASSERT_FALSE(empty < one); + ASSERT_FALSE(empty < positive); + ASSERT_FALSE(empty < negative); + + ASSERT_TRUE(negative < zero); + ASSERT_FALSE(zero < zero); + ASSERT_FALSE(positive < zero); + ASSERT_FALSE(one < zero); + + ASSERT_TRUE(negative < one); + ASSERT_TRUE(zero < one); + ASSERT_FALSE(empty < one); + ASSERT_FALSE(positive < one); + + ASSERT_TRUE(YGFloatOptional{-INFINITY} < negative); + ASSERT_FALSE(empty < negative); +} + +TEST(YGFloatOptional, greater_equals) { + ASSERT_TRUE(empty >= empty); + ASSERT_FALSE(empty >= zero); + ASSERT_FALSE(empty >= one); + ASSERT_FALSE(empty >= positive); + ASSERT_FALSE(empty >= negative); + + ASSERT_TRUE(zero >= negative); + ASSERT_TRUE(zero >= zero); + ASSERT_FALSE(zero >= positive); + ASSERT_FALSE(zero >= one); + + ASSERT_TRUE(one >= negative); + ASSERT_TRUE(one >= zero); + ASSERT_FALSE(one >= empty); + ASSERT_FALSE(one >= positive); + + ASSERT_TRUE(negative >= YGFloatOptional{-INFINITY}); + ASSERT_TRUE(negative >= negative); + ASSERT_FALSE(negative >= empty); +} + +TEST(YGFloatOptional, lower_equals) { + ASSERT_TRUE(empty <= empty); + ASSERT_FALSE(zero <= empty); + ASSERT_FALSE(one <= empty); + ASSERT_FALSE(positive <= empty); + ASSERT_FALSE(negative <= empty); + + ASSERT_TRUE(negative <= zero); + ASSERT_TRUE(zero <= zero); + ASSERT_FALSE(positive <= zero); + ASSERT_FALSE(one <= zero); + + ASSERT_TRUE(negative <= one); + ASSERT_TRUE(zero <= one); + ASSERT_FALSE(empty <= one); + ASSERT_FALSE(positive <= one); + + ASSERT_TRUE(YGFloatOptional{-INFINITY} <= negative); + ASSERT_TRUE(negative <= negative); + ASSERT_FALSE(empty <= negative); +} + +TEST(YGFloatOptional, addition) { + ASSERT_EQ(zero + one, one); + ASSERT_EQ( + negative + positive, + YGFloatOptional{negative.getValue() + positive.getValue()}); + ASSERT_EQ(empty + zero, empty); + ASSERT_EQ(empty + empty, empty); + ASSERT_EQ(negative + empty, empty); +} diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp index d023dccb..0bf89f29 100644 --- a/yoga/YGFloatOptional.cpp +++ b/yoga/YGFloatOptional.cpp @@ -7,23 +7,13 @@ #include "YGFloatOptional.h" #include #include -#include "Yoga.h" #include "Yoga-internal.h" +#include "Yoga.h" using namespace facebook; -YGFloatOptional::YGFloatOptional(float value) { - if (yoga::isUndefined(value)) { - isUndefined_ = true; - value_ = 0; - } else { - value_ = value; - isUndefined_ = false; - } -} - float YGFloatOptional::getValue() const { - if (isUndefined_) { + if (isUndefined()) { // Abort, accessing a value of an undefined float optional std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; std::exit(EXIT_FAILURE); @@ -31,53 +21,38 @@ float YGFloatOptional::getValue() const { return value_; } -bool YGFloatOptional::operator==(const YGFloatOptional& op) const { - if (isUndefined_ == op.isUndefined()) { - return isUndefined_ || value_ == op.getValue(); - } - return false; +bool YGFloatOptional::operator==(YGFloatOptional op) const { + return value_ == op.value_ || (isUndefined() && op.isUndefined()); } -bool YGFloatOptional::operator!=(const YGFloatOptional& op) const { +bool YGFloatOptional::operator!=(YGFloatOptional op) const { return !(*this == op); } bool YGFloatOptional::operator==(float val) const { - if (yoga::isUndefined(val) == isUndefined_) { - return isUndefined_ || val == value_; - } - return false; + return value_ == val || (isUndefined() && yoga::isUndefined(val)); } bool YGFloatOptional::operator!=(float val) const { return !(*this == val); } -YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) { - if (!isUndefined_ && !op.isUndefined_) { - return YGFloatOptional(value_ + op.value_); - } - return YGFloatOptional(); +YGFloatOptional YGFloatOptional::operator+(YGFloatOptional op) const { + return YGFloatOptional{value_ + op.value_}; } -bool YGFloatOptional::operator>(const YGFloatOptional& op) const { - if (isUndefined_ || op.isUndefined_) { - return false; - } +bool YGFloatOptional::operator>(YGFloatOptional op) const { return value_ > op.value_; } -bool YGFloatOptional::operator<(const YGFloatOptional& op) const { - if (isUndefined_ || op.isUndefined_) { - return false; - } +bool YGFloatOptional::operator<(YGFloatOptional op) const { return value_ < op.value_; } -bool YGFloatOptional::operator>=(const YGFloatOptional& op) const { - return *this == op || *this > op; +bool YGFloatOptional::operator>=(YGFloatOptional op) const { + return *this > op || *this == op; } -bool YGFloatOptional::operator<=(const YGFloatOptional& op) const { - return *this == op || *this < op; +bool YGFloatOptional::operator<=(YGFloatOptional op) const { + return *this < op || *this == op; } diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 07fbb64b..7b573d38 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -6,37 +6,33 @@ */ #pragma once +#include +#include + struct YGFloatOptional { private: - float value_ = 0; - bool isUndefined_ = true; + float value_ = std::numeric_limits::quiet_NaN(); public: - explicit YGFloatOptional(float value); - YGFloatOptional() = default; + explicit constexpr YGFloatOptional(float value) : value_(value) {} + constexpr YGFloatOptional() = default; // Program will terminate if the value of an undefined is accessed. Please // make sure to check if the optional is defined before calling this function. // To check if float optional is defined, use `isUndefined()`. float getValue() const; - // Sets the value of float optional, and thus isUndefined is assigned false. - void setValue(float val) { - value_ = val; - isUndefined_ = false; - } - bool isUndefined() const { - return isUndefined_; + return std::isnan(value_); } - YGFloatOptional operator+(const YGFloatOptional& op); - bool operator>(const YGFloatOptional& op) const; - bool operator<(const YGFloatOptional& op) const; - bool operator>=(const YGFloatOptional& op) const; - bool operator<=(const YGFloatOptional& op) const; - bool operator==(const YGFloatOptional& op) const; - bool operator!=(const YGFloatOptional& op) const; + YGFloatOptional operator+(YGFloatOptional op) const; + bool operator>(YGFloatOptional op) const; + bool operator<(YGFloatOptional op) const; + bool operator>=(YGFloatOptional op) const; + bool operator<=(YGFloatOptional op) const; + bool operator==(YGFloatOptional op) const; + bool operator!=(YGFloatOptional op) const; bool operator==(float val) const; bool operator!=(float val) const; diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 1694692c..04c3c7f6 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -211,7 +211,7 @@ YGFloatOptional YGNode::relativePosition( YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize); if (!trailingPosition.isUndefined()) { - trailingPosition.setValue(-1 * trailingPosition.getValue()); + trailingPosition = YGFloatOptional{-1 * trailingPosition.getValue()}; } return trailingPosition; } -- 2.50.1.windows.1 From 50ec35575f8f14f288fa152b86520aab652f714d Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 13/53] Eliminate `YGFloatOptional::getValue()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: @public `YGFloatOptional::getValue()` has the unfortunate property of calling `std::exit` if the wrapped value is undefined. That forces `x.isUndefined() ? fallback : x.getValue()` as access pattern. Here, we replace that by introducing `YGFloatOptional::orElse(float)` which encapsulates that pattern. Other additions are `orElseGet([] { … })` and some extra operators. Reviewed By: SidharthGuglani Differential Revision: D13209152 fbshipit-source-id: 4e5deceaaaaf8eaed44846a8c152cc8b235e815c --- tests/YGFloatOptionalTest.cpp | 56 +++++++++++++++++++++---- yoga/Utils.cpp | 9 ++-- yoga/YGFloatOptional.cpp | 17 ++++---- yoga/YGFloatOptional.h | 27 ++++++++---- yoga/YGNode.cpp | 47 ++++++++------------- yoga/YGNodePrint.cpp | 3 +- yoga/YGStyle.cpp | 37 +++------------- yoga/Yoga.cpp | 79 ++++++++++++++++------------------- 8 files changed, 141 insertions(+), 134 deletions(-) diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp index 2096e5fd..cb4a35a7 100644 --- a/tests/YGFloatOptionalTest.cpp +++ b/tests/YGFloatOptionalTest.cpp @@ -6,7 +6,8 @@ */ #include #include -#include +#include +#include constexpr auto empty = YGFloatOptional{}; constexpr auto zero = YGFloatOptional{0.0f}; @@ -15,9 +16,10 @@ constexpr auto positive = YGFloatOptional{1234.5f}; constexpr auto negative = YGFloatOptional{-9876.5f}; TEST(YGFloatOptional, value) { - ASSERT_EQ(zero.getValue(), 0.0f); - ASSERT_EQ(positive.getValue(), 1234.5f); - ASSERT_EQ(negative.getValue(), -9876.5f); + ASSERT_EQ(zero.unwrap(), 0.0f); + ASSERT_EQ(positive.unwrap(), 1234.5f); + ASSERT_EQ(negative.unwrap(), -9876.5f); + ASSERT_TRUE(YGFloatIsUndefined(empty.unwrap())); ASSERT_TRUE(empty.isUndefined()); ASSERT_FALSE(zero.isUndefined()); @@ -41,7 +43,7 @@ TEST(YGFloatOptional, equality) { ASSERT_FALSE(one == positive); ASSERT_TRUE(negative == negative); - ASSERT_TRUE(negative == negative.getValue()); + ASSERT_TRUE(negative == negative.unwrap()); ASSERT_FALSE(negative == zero); } @@ -62,7 +64,7 @@ TEST(YGFloatOptional, inequality) { ASSERT_TRUE(one != positive); ASSERT_FALSE(negative != negative); - ASSERT_FALSE(negative != negative.getValue()); + ASSERT_FALSE(negative != negative.unwrap()); ASSERT_TRUE(negative != zero); } @@ -72,6 +74,10 @@ TEST(YGFloatOptional, greater) { ASSERT_FALSE(empty > one); ASSERT_FALSE(empty > positive); ASSERT_FALSE(empty > negative); + ASSERT_FALSE(zero > empty); + ASSERT_FALSE(one > empty); + ASSERT_FALSE(positive > empty); + ASSERT_FALSE(negative > empty); ASSERT_TRUE(zero > negative); ASSERT_FALSE(zero > zero); @@ -93,6 +99,10 @@ TEST(YGFloatOptional, lower) { ASSERT_FALSE(empty < one); ASSERT_FALSE(empty < positive); ASSERT_FALSE(empty < negative); + ASSERT_FALSE(zero < empty); + ASSERT_FALSE(one < empty); + ASSERT_FALSE(positive < empty); + ASSERT_FALSE(negative < empty); ASSERT_TRUE(negative < zero); ASSERT_FALSE(zero < zero); @@ -156,8 +166,40 @@ TEST(YGFloatOptional, addition) { ASSERT_EQ(zero + one, one); ASSERT_EQ( negative + positive, - YGFloatOptional{negative.getValue() + positive.getValue()}); + YGFloatOptional{negative.unwrap() + positive.unwrap()}); ASSERT_EQ(empty + zero, empty); ASSERT_EQ(empty + empty, empty); ASSERT_EQ(negative + empty, empty); } + +TEST(YGFloatOptional, subtraction) { + ASSERT_EQ(zero - one, YGFloatOptional{-1.0f}); + ASSERT_EQ( + negative - positive, + YGFloatOptional{negative.unwrap() - positive.unwrap()}); + ASSERT_EQ(empty - zero, empty); + ASSERT_EQ(empty - empty, empty); + ASSERT_EQ(negative - empty, empty); +} + +TEST(YGFloatOptional, unary_minus) { + ASSERT_EQ(-zero, zero); + ASSERT_EQ(-negative, YGFloatOptional{-negative.unwrap()}); + ASSERT_EQ(-positive, YGFloatOptional{-positive.unwrap()}); + ASSERT_EQ(-empty, empty); +} + +TEST(YGFloatOptional, orElse) { + ASSERT_EQ(empty.orElse(1.23f), 1.23f); + ASSERT_TRUE(YGFloatIsUndefined(empty.orElse(YGUndefined))); + ASSERT_EQ(one.orElse(1.23f), 1.0f); +} + +TEST(YGFloatOptional, orElseGet) { + auto x = empty.orElseGet([] { return 1.23f; }); + ASSERT_EQ(x, 1.23f); + ASSERT_TRUE(YGFloatIsUndefined(empty.orElseGet([] { return YGUndefined; }))); + + auto y = one.orElseGet([] { return 1.23f; }); + ASSERT_EQ(y, 1.0f); +} diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 74cc38c9..1d8eb71e 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -56,14 +56,17 @@ float YGFloatSanitize(const float val) { } float YGUnwrapFloatOptional(const YGFloatOptional& op) { - return op.isUndefined() ? YGUndefined : op.getValue(); + return op.unwrap(); } YGFloatOptional YGFloatOptionalMax( const YGFloatOptional& op1, const YGFloatOptional& op2) { - if (!op1.isUndefined() && !op2.isUndefined()) { - return op1.getValue() > op2.getValue() ? op1 : op2; + if (op1 > op2) { + return op1; + } + if (op2 > op1) { + return op2; } return op1.isUndefined() ? op2 : op1; } diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp index 0bf89f29..263f24cb 100644 --- a/yoga/YGFloatOptional.cpp +++ b/yoga/YGFloatOptional.cpp @@ -12,15 +12,6 @@ using namespace facebook; -float YGFloatOptional::getValue() const { - if (isUndefined()) { - // Abort, accessing a value of an undefined float optional - std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; - std::exit(EXIT_FAILURE); - } - return value_; -} - bool YGFloatOptional::operator==(YGFloatOptional op) const { return value_ == op.value_ || (isUndefined() && op.isUndefined()); } @@ -37,10 +28,18 @@ bool YGFloatOptional::operator!=(float val) const { return !(*this == val); } +YGFloatOptional YGFloatOptional::operator-() const { + return YGFloatOptional{-value_}; +} + YGFloatOptional YGFloatOptional::operator+(YGFloatOptional op) const { return YGFloatOptional{value_ + op.value_}; } +YGFloatOptional YGFloatOptional::operator-(YGFloatOptional op) const { + return YGFloatOptional{value_ - op.value_}; +} + bool YGFloatOptional::operator>(YGFloatOptional op) const { return value_ > op.value_; } diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 7b573d38..f6e654fb 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -6,7 +6,6 @@ */ #pragma once -#include #include struct YGFloatOptional { @@ -17,16 +16,28 @@ struct YGFloatOptional { explicit constexpr YGFloatOptional(float value) : value_(value) {} constexpr YGFloatOptional() = default; - // Program will terminate if the value of an undefined is accessed. Please - // make sure to check if the optional is defined before calling this function. - // To check if float optional is defined, use `isUndefined()`. - float getValue() const; - - bool isUndefined() const { - return std::isnan(value_); + // returns the wrapped value, or a value x with YGIsUndefined(x) == true + float unwrap() const { + return value_; } + constexpr bool isUndefined() const { + // std::isnan is not constexpr + return !(value_ == value_); + } + + constexpr float orElse(float other) const { + return isUndefined() ? other : value_; + } + + template + constexpr float orElseGet(Factory&& f) const { + return isUndefined() ? f() : value_; + } + + YGFloatOptional operator-() const; YGFloatOptional operator+(YGFloatOptional op) const; + YGFloatOptional operator-(YGFloatOptional op) const; bool operator>(YGFloatOptional op) const; bool operator<(YGFloatOptional op) const; bool operator>=(YGFloatOptional op) const; diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 04c3c7f6..558a8937 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -209,11 +209,7 @@ YGFloatOptional YGNode::relativePosition( return getLeadingPosition(axis, axisSize); } - YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize); - if (!trailingPosition.isUndefined()) { - trailingPosition = YGFloatOptional{-1 * trailingPosition.getValue()}; - } - return trailingPosition; + return -getTrailingPosition(axis, axisSize); } void YGNode::setPosition( @@ -304,7 +300,7 @@ YGValue YGNode::resolveFlexBasisPtr() const { if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) { return flexBasis; } - if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { + if (style_.flex > YGFloatOptional{0.0f}) { return config_->useWebDefaults ? YGValueAuto : YGValueZero; } return YGValueAuto; @@ -394,27 +390,23 @@ float YGNode::resolveFlexGrow() { if (owner_ == nullptr) { return 0.0; } - if (!style_.flexGrow.isUndefined()) { - return style_.flexGrow.getValue(); - } - if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { - return style_.flex.getValue(); - } - return kDefaultFlexGrow; + + return style_.flexGrow.orElseGet( + [this] { return style_.flex.orElse(kDefaultFlexGrow); }); } float YGNode::resolveFlexShrink() { if (owner_ == nullptr) { return 0.0; } - if (!style_.flexShrink.isUndefined()) { - return style_.flexShrink.getValue(); - } - if (!config_->useWebDefaults && !style_.flex.isUndefined() && - style_.flex.getValue() < 0.0f) { - return -style_.flex.getValue(); - } - return config_->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink; + return style_.flexShrink.orElseGet([this] { + if (style_.flex < YGFloatOptional{0.0f} && !config_->useWebDefaults) { + return -style_.flex.unwrap(); + } else { + return config_->useWebDefaults ? kWebDefaultFlexShrink + : kDefaultFlexShrink; + } + }); } bool YGNode::isNodeFlexible() { @@ -455,9 +447,7 @@ YGFloatOptional YGNode::getLeadingPadding( const float widthSize) const { const YGFloatOptional& paddingEdgeStart = YGResolveValue(style_.padding[YGEdgeStart], widthSize); - if (YGFlexDirectionIsRow(axis) && - style_.padding[YGEdgeStart].unit != YGUnitUndefined && - !paddingEdgeStart.isUndefined() && paddingEdgeStart.getValue() >= 0.0f) { + if (YGFlexDirectionIsRow(axis) && paddingEdgeStart >= YGFloatOptional{0.0f}) { return paddingEdgeStart; } @@ -470,11 +460,10 @@ YGFloatOptional YGNode::getLeadingPadding( YGFloatOptional YGNode::getTrailingPadding( const YGFlexDirection axis, const float widthSize) const { - if (YGFlexDirectionIsRow(axis) && - style_.padding[YGEdgeEnd].unit != YGUnitUndefined && - !YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() && - YGResolveValue(style_.padding[YGEdgeEnd], widthSize).getValue() >= 0.0f) { - return YGResolveValue(style_.padding[YGEdgeEnd], widthSize); + const YGFloatOptional& paddingEdgeEnd = + YGResolveValue(style_.padding[YGEdgeEnd], widthSize); + if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) { + return paddingEdgeEnd; } YGFloatOptional resolvedValue = YGResolveValue( diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 541a6fef..c497996e 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -43,7 +43,7 @@ static void appendFloatOptionalIfDefined( const string key, const YGFloatOptional num) { if (!num.isUndefined()) { - appendFormatedString(base, "%s: %g; ", key.c_str(), num.getValue()); + appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap()); } } @@ -71,7 +71,6 @@ appendNumberIfNotAuto(string* base, const string& key, const YGValue number) { static void appendNumberIfNotZero(string* base, const string& str, const YGValue number) { - if (number.unit == YGUnitAuto) { base->append(str + ": auto; "); } else if (!YGFloatsEqual(number.value, 0)) { diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp index bc90463e..a2f4a17e 100644 --- a/yoga/YGStyle.cpp +++ b/yoga/YGStyle.cpp @@ -8,8 +8,8 @@ // Yoga specific properties, not compatible with flexbox specification bool YGStyle::operator==(const YGStyle& style) { - bool areNonFloatValuesEqual = direction == style.direction && - flexDirection == style.flexDirection && + return ( + direction == style.direction && flexDirection == style.flexDirection && justifyContent == style.justifyContent && alignContent == style.alignContent && alignItems == style.alignItems && alignSelf == style.alignSelf && positionType == style.positionType && @@ -21,34 +21,7 @@ bool YGStyle::operator==(const YGStyle& style) { YGValueArrayEqual(border, style.border) && YGValueArrayEqual(dimensions, style.dimensions) && YGValueArrayEqual(minDimensions, style.minDimensions) && - YGValueArrayEqual(maxDimensions, style.maxDimensions); - - areNonFloatValuesEqual = - areNonFloatValuesEqual && flex.isUndefined() == style.flex.isUndefined(); - if (areNonFloatValuesEqual && !flex.isUndefined() && - !style.flex.isUndefined()) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && flex.getValue() == style.flex.getValue(); - } - - areNonFloatValuesEqual = areNonFloatValuesEqual && - flexGrow.isUndefined() == style.flexGrow.isUndefined(); - if (areNonFloatValuesEqual && !flexGrow.isUndefined()) { - areNonFloatValuesEqual = areNonFloatValuesEqual && - flexGrow.getValue() == style.flexGrow.getValue(); - } - - areNonFloatValuesEqual = areNonFloatValuesEqual && - flexShrink.isUndefined() == style.flexShrink.isUndefined(); - if (areNonFloatValuesEqual && !style.flexShrink.isUndefined()) { - areNonFloatValuesEqual = areNonFloatValuesEqual && - flexShrink.getValue() == style.flexShrink.getValue(); - } - - if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) { - areNonFloatValuesEqual = areNonFloatValuesEqual && - aspectRatio.getValue() == style.aspectRatio.getValue(); - } - - return areNonFloatValuesEqual; + YGValueArrayEqual(maxDimensions, style.maxDimensions) && + flex == style.flex && flexGrow == style.flexGrow && + flexShrink == style.flexShrink && aspectRatio == style.aspectRatio); } diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 246e0f41..5197d994 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -579,16 +579,14 @@ void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode) { } float YGNodeStyleGetFlexGrow(const YGNodeRef node) { - return node->getStyle().flexGrow.isUndefined() - ? kDefaultFlexGrow - : node->getStyle().flexGrow.getValue(); + return node->getStyle().flexGrow.orElse(kDefaultFlexGrow); } float YGNodeStyleGetFlexShrink(const YGNodeRef node) { - return node->getStyle().flexShrink.isUndefined() - ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink - : kDefaultFlexShrink) - : node->getStyle().flexShrink.getValue(); + return node->getStyle().flexShrink.orElseGet([node] { + return node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink + : kDefaultFlexShrink; + }); } namespace { @@ -856,8 +854,7 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { // TODO(T26792433): Change the API to accept YGFloatOptional. float YGNodeStyleGetFlex(const YGNodeRef node) { - return node->getStyle().flex.isUndefined() ? YGUndefined - : node->getStyle().flex.getValue(); + return node->getStyle().flex.orElse(YGUndefined); } // TODO(T26792433): Change the API to accept YGFloatOptional. @@ -959,7 +956,7 @@ float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) { // TODO(T26792433): Change the API to accept YGFloatOptional. float YGNodeStyleGetAspectRatio(const YGNodeRef node) { const YGFloatOptional op = node->getStyle().aspectRatio; - return op.isUndefined() ? YGUndefined : op.getValue(); + return op.orElse(YGUndefined); } // TODO(T26792433): Change the API to accept YGFloatOptional. @@ -1229,15 +1226,15 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( node->getStyle().maxDimensions[YGDimensionWidth], axisSize); } - if (!max.isUndefined() && max.getValue() >= 0 && value > max.getValue()) { + if (max >= YGFloatOptional{0} && YGFloatOptional{value} > max) { return max; } - if (!min.isUndefined() && min.getValue() >= 0 && value < min.getValue()) { + if (min >= YGFloatOptional{0} && YGFloatOptional{value} < min) { return min; } - return YGFloatOptional(value); + return YGFloatOptional{value}; } // Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't @@ -1278,14 +1275,14 @@ static void YGConstrainMaxSizeForMode( switch (*mode) { case YGMeasureModeExactly: case YGMeasureModeAtMost: - *size = (maxSize.isUndefined() || *size < maxSize.getValue()) - ? *size - : maxSize.getValue(); + if (YGFloatOptional{*size} > maxSize) { + *size = maxSize.unwrap(); + } break; case YGMeasureModeUndefined: if (!maxSize.isUndefined()) { *mode = YGMeasureModeAtMost; - *size = maxSize.getValue(); + *size = maxSize.unwrap(); } break; } @@ -1395,16 +1392,15 @@ static void YGNodeComputeFlexBasisForChild( } } - if (!child->getStyle().aspectRatio.isUndefined()) { + auto hasAspectRatio = !child->getStyle().aspectRatio.isUndefined(); + auto aspectRatio = child->getStyle().aspectRatio.unwrap(); + if (hasAspectRatio) { if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { - childHeight = marginColumn + - (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + childHeight = marginColumn + (childWidth - marginRow) / aspectRatio; childHeightMeasureMode = YGMeasureModeExactly; } else if ( isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { - childWidth = marginRow + - (childHeight - marginColumn) * - child->getStyle().aspectRatio.getValue(); + childWidth = marginRow + (childHeight - marginColumn) * aspectRatio; childWidthMeasureMode = YGMeasureModeExactly; } } @@ -1422,9 +1418,8 @@ static void YGNodeComputeFlexBasisForChild( childWidthStretch) { childWidth = width; childWidthMeasureMode = YGMeasureModeExactly; - if (!child->getStyle().aspectRatio.isUndefined()) { - childHeight = - (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + if (hasAspectRatio) { + childHeight = (childWidth - marginRow) / aspectRatio; childHeightMeasureMode = YGMeasureModeExactly; } } @@ -1439,9 +1434,8 @@ static void YGNodeComputeFlexBasisForChild( childHeight = height; childHeightMeasureMode = YGMeasureModeExactly; - if (!child->getStyle().aspectRatio.isUndefined()) { - childWidth = (childHeight - marginColumn) * - child->getStyle().aspectRatio.getValue(); + if (hasAspectRatio) { + childWidth = (childHeight - marginColumn) * aspectRatio; childWidthMeasureMode = YGMeasureModeExactly; } } @@ -1553,13 +1547,11 @@ static void YGNodeAbsoluteLayoutChild( // flexible. if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) { if (!child->getStyle().aspectRatio.isUndefined()) { + auto aspectRatio = child->getStyle().aspectRatio.unwrap(); if (YGFloatIsUndefined(childWidth)) { - childWidth = marginRow + - (childHeight - marginColumn) * - child->getStyle().aspectRatio.getValue(); + childWidth = marginRow + (childHeight - marginColumn) * aspectRatio; } else if (YGFloatIsUndefined(childHeight)) { - childHeight = marginColumn + - (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + childHeight = marginColumn + (childWidth - marginRow) / aspectRatio; } } } @@ -1885,16 +1877,15 @@ static float YGNodeCalculateAvailableInnerDim( // constraints const YGFloatOptional minDimensionOptional = YGResolveValue(node->getStyle().minDimensions[dimension], ownerDim); - const float minInnerDim = minDimensionOptional.isUndefined() - ? 0.0f - : minDimensionOptional.getValue() - paddingAndBorder; + const float minInnerDim = + (minDimensionOptional - YGFloatOptional{paddingAndBorder}).orElse(0.0f); const YGFloatOptional maxDimensionOptional = YGResolveValue(node->getStyle().maxDimensions[dimension], ownerDim); - const float maxInnerDim = maxDimensionOptional.isUndefined() - ? FLT_MAX - : maxDimensionOptional.getValue() - paddingAndBorder; + const float maxInnerDim = + (maxDimensionOptional - YGFloatOptional{paddingAndBorder}) + .orElse(FLT_MAX); availableInnerDim = YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim); } @@ -2162,9 +2153,9 @@ static float YGDistributeFreeSpaceSecondPass( if (!currentRelativeChild->getStyle().aspectRatio.isUndefined()) { childCrossSize = isMainAxisRow ? (childMainSize - marginMain) / - currentRelativeChild->getStyle().aspectRatio.getValue() + currentRelativeChild->getStyle().aspectRatio.unwrap() : (childMainSize - marginMain) * - currentRelativeChild->getStyle().aspectRatio.getValue(); + currentRelativeChild->getStyle().aspectRatio.unwrap(); childCrossMeasureMode = YGMeasureModeExactly; childCrossSize += marginCross; @@ -3131,9 +3122,9 @@ static void YGNodelayoutImpl( ? ((YGUnwrapFloatOptional(child->getMarginForAxis( crossAxis, availableInnerWidth)) + (isMainAxisRow ? childMainSize / - child->getStyle().aspectRatio.getValue() + child->getStyle().aspectRatio.unwrap() : childMainSize * - child->getStyle().aspectRatio.getValue()))) + child->getStyle().aspectRatio.unwrap()))) : collectedFlexItemsValues.crossDim; childMainSize += YGUnwrapFloatOptional( -- 2.50.1.windows.1 From 64c37767c25e86e66e9ef513dc800e54e4d1ac3b Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 14/53] Pass `YGFloatOptional` by value, not reference Summary: @public `YGFloatOptional` is a 32bit type now, and can be passed by value efficiently. Reviewed By: SidharthGuglani Differential Revision: D13209150 fbshipit-source-id: c7b937a640258256c97e082ba2f832754e191b9a --- yoga/Utils.cpp | 6 +++--- yoga/Utils.h | 6 +++--- yoga/YGNode.cpp | 6 +++--- yoga/YGNode.h | 2 +- yoga/Yoga.cpp | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 1d8eb71e..88ebd841 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -55,13 +55,13 @@ float YGFloatSanitize(const float val) { return yoga::isUndefined(val) ? 0 : val; } -float YGUnwrapFloatOptional(const YGFloatOptional& op) { +float YGUnwrapFloatOptional(const YGFloatOptional op) { return op.unwrap(); } YGFloatOptional YGFloatOptionalMax( - const YGFloatOptional& op1, - const YGFloatOptional& op2) { + const YGFloatOptional op1, + const YGFloatOptional op2) { if (op1 > op2) { return op1; } diff --git a/yoga/Utils.h b/yoga/Utils.h index d007ff54..204b2718 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -60,8 +60,8 @@ bool YGFloatsEqual(const float a, const float b); float YGFloatMax(const float a, const float b); YGFloatOptional YGFloatOptionalMax( - const YGFloatOptional& op1, - const YGFloatOptional& op2); + const YGFloatOptional op1, + const YGFloatOptional op2); float YGFloatMin(const float a, const float b); @@ -85,7 +85,7 @@ float YGFloatSanitize(const float val); // This function unwraps optional and returns YGUndefined if not defined or // op.value otherwise // TODO: Get rid off this function -float YGUnwrapFloatOptional(const YGFloatOptional& op); +float YGUnwrapFloatOptional(const YGFloatOptional op); YGFlexDirection YGFlexDirectionCross( const YGFlexDirection flexDirection, diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 558a8937..83c1eabd 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -175,7 +175,7 @@ void YGNode::setLayoutLastOwnerDirection(YGDirection direction) { } void YGNode::setLayoutComputedFlexBasis( - const YGFloatOptional& computedFlexBasis) { + const YGFloatOptional computedFlexBasis) { layout_.computedFlexBasis = computedFlexBasis; } @@ -445,7 +445,7 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const { YGFloatOptional YGNode::getLeadingPadding( const YGFlexDirection axis, const float widthSize) const { - const YGFloatOptional& paddingEdgeStart = + const YGFloatOptional paddingEdgeStart = YGResolveValue(style_.padding[YGEdgeStart], widthSize); if (YGFlexDirectionIsRow(axis) && paddingEdgeStart >= YGFloatOptional{0.0f}) { return paddingEdgeStart; @@ -460,7 +460,7 @@ YGFloatOptional YGNode::getLeadingPadding( YGFloatOptional YGNode::getTrailingPadding( const YGFlexDirection axis, const float widthSize) const { - const YGFloatOptional& paddingEdgeEnd = + const YGFloatOptional paddingEdgeEnd = YGResolveValue(style_.padding[YGEdgeEnd], widthSize); if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) { return paddingEdgeEnd; diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 719eb2ea..57312812 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -235,7 +235,7 @@ struct YGNode { void setDirty(bool isDirty); void setLayoutLastOwnerDirection(YGDirection direction); - void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis); + void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis); void setLayoutComputedFlexBasisGeneration( uint32_t computedFlexBasisGeneration); void setLayoutMeasuredDimension(float measuredDimension, int index); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 5197d994..e708f61c 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1323,14 +1323,14 @@ static void YGNodeComputeFlexBasisForChild( child->getConfig(), YGExperimentalFeatureWebFlexBasis) && child->getLayout().computedFlexBasisGeneration != gCurrentGenerationCount)) { - const YGFloatOptional& paddingAndBorder = YGFloatOptional( + const YGFloatOptional paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); child->setLayoutComputedFlexBasis( YGFloatOptionalMax(resolvedFlexBasis, paddingAndBorder)); } } else if (isMainAxisRow && isRowStyleDimDefined) { // The width is definite, so use that as the flex basis. - const YGFloatOptional& paddingAndBorder = YGFloatOptional( + const YGFloatOptional paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( @@ -1339,7 +1339,7 @@ static void YGNodeComputeFlexBasisForChild( paddingAndBorder)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { // The height is definite, so use that as the flex basis. - const YGFloatOptional& paddingAndBorder = + const YGFloatOptional paddingAndBorder = YGFloatOptional(YGNodePaddingAndBorderForAxis( child, YGFlexDirectionColumn, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( -- 2.50.1.windows.1 From 59755d2874e8c47f707bdcafa59a1fc40c7570e3 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 15/53] Inline `YGFloatOptional` completely Summary: @public `YGFLoatOptional` only contains trivial functionality. Make it header-only. Reviewed By: SidharthGuglani Differential Revision: D13209151 fbshipit-source-id: 3ecca015fa0ac6644ae694b44bc53d840fbc5635 --- yoga/YGFloatOptional.cpp | 57 ---------------------------------------- yoga/YGFloatOptional.h | 47 ++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 69 deletions(-) delete mode 100644 yoga/YGFloatOptional.cpp diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp deleted file mode 100644 index 263f24cb..00000000 --- a/yoga/YGFloatOptional.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. - */ -#include "YGFloatOptional.h" -#include -#include -#include "Yoga-internal.h" -#include "Yoga.h" - -using namespace facebook; - -bool YGFloatOptional::operator==(YGFloatOptional op) const { - return value_ == op.value_ || (isUndefined() && op.isUndefined()); -} - -bool YGFloatOptional::operator!=(YGFloatOptional op) const { - return !(*this == op); -} - -bool YGFloatOptional::operator==(float val) const { - return value_ == val || (isUndefined() && yoga::isUndefined(val)); -} - -bool YGFloatOptional::operator!=(float val) const { - return !(*this == val); -} - -YGFloatOptional YGFloatOptional::operator-() const { - return YGFloatOptional{-value_}; -} - -YGFloatOptional YGFloatOptional::operator+(YGFloatOptional op) const { - return YGFloatOptional{value_ + op.value_}; -} - -YGFloatOptional YGFloatOptional::operator-(YGFloatOptional op) const { - return YGFloatOptional{value_ - op.value_}; -} - -bool YGFloatOptional::operator>(YGFloatOptional op) const { - return value_ > op.value_; -} - -bool YGFloatOptional::operator<(YGFloatOptional op) const { - return value_ < op.value_; -} - -bool YGFloatOptional::operator>=(YGFloatOptional op) const { - return *this > op || *this == op; -} - -bool YGFloatOptional::operator<=(YGFloatOptional op) const { - return *this < op || *this == op; -} diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index f6e654fb..3dd3d5c9 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -7,6 +7,7 @@ #pragma once #include +#include "Yoga-internal.h" struct YGFloatOptional { private: @@ -17,7 +18,7 @@ struct YGFloatOptional { constexpr YGFloatOptional() = default; // returns the wrapped value, or a value x with YGIsUndefined(x) == true - float unwrap() const { + constexpr float unwrap() const { return value_; } @@ -35,16 +36,38 @@ struct YGFloatOptional { return isUndefined() ? f() : value_; } - YGFloatOptional operator-() const; - YGFloatOptional operator+(YGFloatOptional op) const; - YGFloatOptional operator-(YGFloatOptional op) const; - bool operator>(YGFloatOptional op) const; - bool operator<(YGFloatOptional op) const; - bool operator>=(YGFloatOptional op) const; - bool operator<=(YGFloatOptional op) const; - bool operator==(YGFloatOptional op) const; - bool operator!=(YGFloatOptional op) const; + YGFloatOptional operator-() const { + return YGFloatOptional{-value_}; + } + YGFloatOptional operator+(YGFloatOptional op) const { + return YGFloatOptional{value_ + op.value_}; + } + YGFloatOptional operator-(YGFloatOptional op) const { + return YGFloatOptional{value_ - op.value_}; + } + bool operator>(YGFloatOptional op) const { + return value_ > op.value_; + } + bool operator<(YGFloatOptional op) const { + return value_ < op.value_; + } + bool operator>=(YGFloatOptional op) const { + return *this > op || *this == op; + } + bool operator<=(YGFloatOptional op) const { + return *this < op || *this == op; + } + bool operator==(YGFloatOptional op) const { + return value_ == op.value_ || (isUndefined() && op.isUndefined()); + } + bool operator!=(YGFloatOptional op) const { + return !(*this == op); + } - bool operator==(float val) const; - bool operator!=(float val) const; + bool operator==(float val) const { + return value_ == val || (isUndefined() && yoga::isUndefined(val)); + } + bool operator!=(float val) const { + return !(*this == val); + } }; -- 2.50.1.windows.1 From 9680ae98a69d62b8c4308be554b35515de62678a Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 16/53] Get rid of `static_cast` in `YGResolveValue` Summary: @public Removes `static_cast` from `YGResolveValue` Reviewed By: SidharthGuglani Differential Revision: D13209155 fbshipit-source-id: 76c27c89f6217af9dfef9e2620d639c9f3e212f5 --- yoga/Utils.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/yoga/Utils.h b/yoga/Utils.h index 204b2718..2a52eb2a 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -100,16 +100,13 @@ inline YGFloatOptional YGResolveValue( const YGValue value, const float ownerSize) { switch (value.unit) { - case YGUnitUndefined: - case YGUnitAuto: - return YGFloatOptional(); case YGUnitPoint: - return YGFloatOptional(value.value); + return YGFloatOptional{value.value}; case YGUnitPercent: - return YGFloatOptional( - static_cast(value.value * ownerSize * 0.01)); + return YGFloatOptional{value.value * ownerSize * 0.01f}; + default: + return YGFloatOptional{}; } - return YGFloatOptional(); } inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { -- 2.50.1.windows.1 From b6498987faf60cb0c09e0f056e60b9d348b3fa12 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 17/53] Remove unnecessary `static` keyword MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: @public Header-declared inline functions shouldn’t be decleared `static` Reviewed By: SidharthGuglani Differential Revision: D13209156 fbshipit-source-id: e2d643a67e6f6c33c96dc71b0a90d00bd9b6f36f --- yoga/Utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yoga/Utils.h b/yoga/Utils.h index 2a52eb2a..7357009c 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -128,7 +128,7 @@ inline YGFlexDirection YGResolveFlexDirection( return flexDirection; } -static inline YGFloatOptional YGResolveValueMargin( +inline YGFloatOptional YGResolveValueMargin( const YGValue value, const float ownerSize) { return value.unit == YGUnitAuto ? YGFloatOptional(0) -- 2.50.1.windows.1 From 10b316f31551b7e60708cae1c225baf44c3eee4c Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 18/53] inline `YGUnwrapFloatOptional` Summary: @public Replaces C-style function call with C++ method invokation. Reviewed By: SidharthGuglani Differential Revision: D13209154 fbshipit-source-id: 14e650af4655efb3a659f3cd949a11df773aabcf --- yoga/Utils.cpp | 4 - yoga/Utils.h | 5 - yoga/YGNode.cpp | 14 +- yoga/Yoga.cpp | 390 +++++++++++++++++++++++++----------------------- 4 files changed, 212 insertions(+), 201 deletions(-) diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 88ebd841..b246f943 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -55,10 +55,6 @@ float YGFloatSanitize(const float val) { return yoga::isUndefined(val) ? 0 : val; } -float YGUnwrapFloatOptional(const YGFloatOptional op) { - return op.unwrap(); -} - YGFloatOptional YGFloatOptionalMax( const YGFloatOptional op1, const YGFloatOptional op2) { diff --git a/yoga/Utils.h b/yoga/Utils.h index 7357009c..a0d49235 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -82,11 +82,6 @@ bool YGFloatArrayEqual( // This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise float YGFloatSanitize(const float val); -// This function unwraps optional and returns YGUndefined if not defined or -// op.value otherwise -// TODO: Get rid off this function -float YGUnwrapFloatOptional(const YGFloatOptional op); - YGFlexDirection YGFlexDirectionCross( const YGFlexDirection flexDirection, const YGDirection direction); diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 83c1eabd..9ae03b01 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -232,20 +232,18 @@ void YGNode::setPosition( relativePosition(crossAxis, crossSize); setLayoutPosition( - YGUnwrapFloatOptional( - getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain), + (getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), leading[mainAxis]); setLayoutPosition( - YGUnwrapFloatOptional( - getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain), + (getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), trailing[mainAxis]); setLayoutPosition( - YGUnwrapFloatOptional( - getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross), + (getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross) + .unwrap(), leading[crossAxis]); setLayoutPosition( - YGUnwrapFloatOptional( - getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross), + (getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross) + .unwrap(), trailing[crossAxis]); } diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index e708f61c..e000ab1d 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1093,9 +1093,9 @@ static inline float YGNodePaddingAndBorderForAxis( const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return YGUnwrapFloatOptional( - node->getLeadingPaddingAndBorder(axis, widthSize) + - node->getTrailingPaddingAndBorder(axis, widthSize)); + return (node->getLeadingPaddingAndBorder(axis, widthSize) + + node->getTrailingPaddingAndBorder(axis, widthSize)) + .unwrap(); } static inline YGAlign YGNodeAlignItem( @@ -1177,9 +1177,9 @@ static inline float YGNodeDimWithMargin( const YGFlexDirection axis, const float widthSize) { return node->getLayout().measuredDimensions[dim[axis]] + - YGUnwrapFloatOptional( - node->getLeadingMargin(axis, widthSize) + - node->getTrailingMargin(axis, widthSize)); + (node->getLeadingMargin(axis, widthSize) + + node->getTrailingMargin(axis, widthSize)) + .unwrap(); } static inline bool YGNodeIsStyleDimDefined( @@ -1246,8 +1246,7 @@ static inline float YGNodeBoundAxis( const float axisSize, const float widthSize) { return YGFloatMax( - YGUnwrapFloatOptional( - YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize)), + (YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize)).unwrap(), YGNodePaddingAndBorderForAxis(node, axis, widthSize)); } @@ -1354,22 +1353,24 @@ static void YGNodeComputeFlexBasisForChild( childWidthMeasureMode = YGMeasureModeUndefined; childHeightMeasureMode = YGMeasureModeUndefined; - auto marginRow = YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - auto marginColumn = YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + auto marginRow = + (child->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); + auto marginColumn = + (child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); if (isRowStyleDimDefined) { childWidth = - YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionWidth), ownerWidth)) + + (YGResolveValue( + child->getResolvedDimension(YGDimensionWidth), ownerWidth)) + .unwrap() + marginRow; childWidthMeasureMode = YGMeasureModeExactly; } if (isColumnStyleDimDefined) { childHeight = - YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionHeight), ownerHeight)) + + (YGResolveValue( + child->getResolvedDimension(YGDimensionHeight), ownerHeight)) + .unwrap() + marginColumn; childHeightMeasureMode = YGMeasureModeExactly; } @@ -1495,13 +1496,14 @@ static void YGNodeAbsoluteLayoutChild( YGMeasureMode childHeightMeasureMode = YGMeasureModeUndefined; auto marginRow = - YGUnwrapFloatOptional(child->getMarginForAxis(YGFlexDirectionRow, width)); - auto marginColumn = YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionColumn, width)); + (child->getMarginForAxis(YGFlexDirectionRow, width)).unwrap(); + auto marginColumn = + (child->getMarginForAxis(YGFlexDirectionColumn, width)).unwrap(); if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { - childWidth = YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionWidth), width)) + + childWidth = + (YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width)) + .unwrap() + marginRow; } else { // If the child doesn't have a specified width, compute the width based @@ -1512,17 +1514,18 @@ static void YGNodeAbsoluteLayoutChild( childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - (node->getLeadingBorder(YGFlexDirectionRow) + node->getTrailingBorder(YGFlexDirectionRow)) - - YGUnwrapFloatOptional( - child->getLeadingPosition(YGFlexDirectionRow, width) + - child->getTrailingPosition(YGFlexDirectionRow, width)); + (child->getLeadingPosition(YGFlexDirectionRow, width) + + child->getTrailingPosition(YGFlexDirectionRow, width)) + .unwrap(); childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); } } if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { - childHeight = YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionHeight), height)) + + childHeight = + (YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height)) + .unwrap() + marginColumn; } else { // If the child doesn't have a specified height, compute the height @@ -1530,13 +1533,12 @@ static void YGNodeAbsoluteLayoutChild( // offsets if they're defined. if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && child->isTrailingPosDefined(YGFlexDirectionColumn)) { - childHeight = - node->getLayout().measuredDimensions[YGDimensionHeight] - + childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - (node->getLeadingBorder(YGFlexDirectionColumn) + node->getTrailingBorder(YGFlexDirectionColumn)) - - YGUnwrapFloatOptional( - child->getLeadingPosition(YGFlexDirectionColumn, height) + - child->getTrailingPosition(YGFlexDirectionColumn, height)); + (child->getLeadingPosition(YGFlexDirectionColumn, height) + + child->getTrailingPosition(YGFlexDirectionColumn, height)) + .unwrap(); childHeight = YGNodeBoundAxis( child, YGFlexDirectionColumn, childHeight, height, width); } @@ -1589,11 +1591,9 @@ static void YGNodeAbsoluteLayoutChild( "abs-measure", config); childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + - YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionRow, width)); + (child->getMarginForAxis(YGFlexDirectionRow, width)).unwrap(); childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionColumn, width)); + (child->getMarginForAxis(YGFlexDirectionColumn, width)).unwrap(); } YGLayoutNodeInternal( @@ -1615,9 +1615,10 @@ static void YGNodeAbsoluteLayoutChild( node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]] - node->getTrailingBorder(mainAxis) - - YGUnwrapFloatOptional(child->getTrailingMargin(mainAxis, width)) - - YGUnwrapFloatOptional(child->getTrailingPosition( - mainAxis, isMainAxisRow ? width : height)), + (child->getTrailingMargin(mainAxis, width)).unwrap() - + (child->getTrailingPosition( + mainAxis, isMainAxisRow ? width : height)) + .unwrap(), leading[mainAxis]); } else if ( !child->isLeadingPositionDefined(mainAxis) && @@ -1642,9 +1643,10 @@ static void YGNodeAbsoluteLayoutChild( node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]] - node->getTrailingBorder(crossAxis) - - YGUnwrapFloatOptional(child->getTrailingMargin(crossAxis, width)) - - YGUnwrapFloatOptional(child->getTrailingPosition( - crossAxis, isMainAxisRow ? height : width)), + (child->getTrailingMargin(crossAxis, width)).unwrap() - + (child->getTrailingPosition( + crossAxis, isMainAxisRow ? height : width)) + .unwrap(), leading[crossAxis]); } else if ( @@ -1683,10 +1685,10 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis( node, YGFlexDirectionColumn, availableWidth); - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, availableWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, availableWidth)); + const float marginAxisRow = + (node->getMarginForAxis(YGFlexDirectionRow, availableWidth)).unwrap(); + const float marginAxisColumn = + (node->getMarginForAxis(YGFlexDirectionColumn, availableWidth)).unwrap(); // We want to make sure we don't call measure with negative size const float innerWidth = YGFloatIsUndefined(availableWidth) @@ -1761,10 +1763,10 @@ static void YGNodeEmptyContainerSetMeasuredDimensions( YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + const float marginAxisRow = + (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); + const float marginAxisColumn = + (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); node->setLayoutMeasuredDimension( YGNodeBoundAxis( @@ -1805,10 +1807,10 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) || (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly)) { - auto marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); - auto marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + auto marginAxisColumn = + (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); + auto marginAxisRow = + (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); node->setLayoutMeasuredDimension( YGNodeBoundAxis( @@ -1864,8 +1866,7 @@ static float YGNodeCalculateAvailableInnerDim( YGDimension dimension = YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight; - const float margin = - YGUnwrapFloatOptional(node->getMarginForAxis(direction, ownerDim)); + const float margin = (node->getMarginForAxis(direction, ownerDim)).unwrap(); const float paddingAndBorder = YGNodePaddingAndBorderForAxis(node, direction, ownerDim); @@ -1969,9 +1970,10 @@ static float YGNodeComputeFlexBasisForChildren( config); } - totalOuterFlexBasis += YGUnwrapFloatOptional( - child->getLayout().computedFlexBasis + - child->getMarginForAxis(mainAxis, availableInnerWidth)); + totalOuterFlexBasis += + (child->getLayout().computedFlexBasis + + child->getMarginForAxis(mainAxis, availableInnerWidth)) + .unwrap(); } return totalOuterFlexBasis; @@ -2006,14 +2008,15 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( continue; } child->setLineIndex(lineCount); - const float childMarginMainAxis = YGUnwrapFloatOptional( - child->getMarginForAxis(mainAxis, availableInnerWidth)); + const float childMarginMainAxis = + (child->getMarginForAxis(mainAxis, availableInnerWidth)).unwrap(); const float flexBasisWithMinAndMaxConstraints = - YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - child, - mainAxis, - YGUnwrapFloatOptional(child->getLayout().computedFlexBasis), - mainAxisownerSize)); + (YGNodeBoundAxisWithinMinAndMax( + child, + mainAxis, + (child->getLayout().computedFlexBasis).unwrap(), + mainAxisownerSize)) + .unwrap(); // If this is a multi-line flow and this item pushes us over the // available size, we've @@ -2039,7 +2042,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( // child dimension. flexAlgoRowMeasurement.totalFlexShrinkScaledFactors += -child->resolveFlexShrink() * - YGUnwrapFloatOptional(child->getLayout().computedFlexBasis); + (child->getLayout().computedFlexBasis).unwrap(); } flexAlgoRowMeasurement.relativeChildren.push_back(child); @@ -2086,12 +2089,13 @@ static float YGDistributeFreeSpaceSecondPass( const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - YGUnwrapFloatOptional( - currentRelativeChild->getLayout().computedFlexBasis), - mainAxisownerSize)); + childFlexBasis = + (YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + (currentRelativeChild->getLayout().computedFlexBasis).unwrap(), + mainAxisownerSize)) + .unwrap(); float updatedMainSize = childFlexBasis; if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && @@ -2141,10 +2145,12 @@ static float YGDistributeFreeSpaceSecondPass( deltaFreeSpace += updatedMainSize - childFlexBasis; - const float marginMain = YGUnwrapFloatOptional( - currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth)); - const float marginCross = YGUnwrapFloatOptional( - currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth)); + const float marginMain = + (currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth)) + .unwrap(); + const float marginCross = + (currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth)) + .unwrap(); float childCrossSize; float childMainSize = updatedMainSize + marginMain; @@ -2180,9 +2186,10 @@ static float YGDistributeFreeSpaceSecondPass( : YGMeasureModeAtMost; } else { childCrossSize = - YGUnwrapFloatOptional(YGResolveValue( - currentRelativeChild->getResolvedDimension(dim[crossAxis]), - availableInnerCrossDim)) + + (YGResolveValue( + currentRelativeChild->getResolvedDimension(dim[crossAxis]), + availableInnerCrossDim)) + .unwrap() + marginCross; const bool isLoosePercentageMeasurement = currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit == @@ -2262,12 +2269,13 @@ static void YGDistributeFreeSpaceFirstPass( float deltaFreeSpace = 0; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - float childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - YGUnwrapFloatOptional( - currentRelativeChild->getLayout().computedFlexBasis), - mainAxisownerSize)); + float childFlexBasis = + (YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + (currentRelativeChild->getLayout().computedFlexBasis).unwrap(), + mainAxisownerSize)) + .unwrap(); if (collectedFlexItemsValues.remainingFreeSpace < 0) { flexShrinkScaledFactor = @@ -2418,10 +2426,10 @@ static void YGJustifyMainAxis( const float availableInnerWidth, const bool performLayout) { const YGStyle& style = node->getStyle(); - const float leadingPaddingAndBorderMain = YGUnwrapFloatOptional( - node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)); - const float trailingPaddingAndBorderMain = YGUnwrapFloatOptional( - node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)); + const float leadingPaddingAndBorderMain = + (node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)).unwrap(); + const float trailingPaddingAndBorderMain = + (node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)).unwrap(); // If we are using "at most" rules in the main axis, make sure that // remainingFreeSpace is 0 when min main dimension is not given if (measureModeMainDim == YGMeasureModeAtMost && @@ -2437,8 +2445,9 @@ static void YGJustifyMainAxis( // `minAvailableMainDim` denotes minimum available space in which child // can be laid out, it will exclude space consumed by padding and border. const float minAvailableMainDim = - YGUnwrapFloatOptional(YGResolveValue( - style.minDimensions[dim[mainAxis]], mainAxisownerSize)) - + (YGResolveValue( + style.minDimensions[dim[mainAxis]], mainAxisownerSize)) + .unwrap() - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; const float occupiedSpaceByChildNodes = availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace; @@ -2528,11 +2537,11 @@ static void YGJustifyMainAxis( // defined, we override the position to whatever the user said // (and margin/border). child->setLayoutPosition( - YGUnwrapFloatOptional( - child->getLeadingPosition(mainAxis, availableInnerMainDim)) + + (child->getLeadingPosition(mainAxis, availableInnerMainDim)) + .unwrap() + node->getLeadingBorder(mainAxis) + - YGUnwrapFloatOptional( - child->getLeadingMargin(mainAxis, availableInnerWidth)), + (child->getLeadingMargin(mainAxis, availableInnerWidth)) + .unwrap(), pos[mainAxis]); } } else { @@ -2566,9 +2575,9 @@ static void YGJustifyMainAxis( // they weren't computed. This means we can't call // YGNodeDimWithMargin. collectedFlexItemsValues.mainDim += betweenMainDim + - YGUnwrapFloatOptional(child->getMarginForAxis( - mainAxis, availableInnerWidth)) + - YGUnwrapFloatOptional(childLayout.computedFlexBasis); + (child->getMarginForAxis(mainAxis, availableInnerWidth)) + .unwrap() + + (childLayout.computedFlexBasis).unwrap(); collectedFlexItemsValues.crossDim = availableInnerCrossDim; } else { // The main dimension is the sum of all the elements dimension plus @@ -2580,12 +2589,14 @@ static void YGJustifyMainAxis( // If the child is baseline aligned then the cross dimension is // calculated by adding maxAscent and maxDescent from the baseline. const float ascent = YGBaseline(child) + - YGUnwrapFloatOptional(child->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth)); + (child->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth)) + .unwrap(); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional(child->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth)) - + (child->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth)) + .unwrap() - ascent; maxAscentForCurrentLine = @@ -2738,20 +2749,16 @@ static void YGNodelayoutImpl( YGResolveFlexDirection(YGFlexDirectionColumn, direction); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getLeadingMargin(flexRowDirection, ownerWidth)), + (node->getLeadingMargin(flexRowDirection, ownerWidth)).unwrap(), YGEdgeStart); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getTrailingMargin(flexRowDirection, ownerWidth)), + (node->getTrailingMargin(flexRowDirection, ownerWidth)).unwrap(), YGEdgeEnd); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getLeadingMargin(flexColumnDirection, ownerWidth)), + (node->getLeadingMargin(flexColumnDirection, ownerWidth)).unwrap(), YGEdgeTop); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getTrailingMargin(flexColumnDirection, ownerWidth)), + (node->getTrailingMargin(flexColumnDirection, ownerWidth)).unwrap(), YGEdgeBottom); node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), YGEdgeStart); @@ -2761,20 +2768,16 @@ static void YGNodelayoutImpl( node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getLeadingPadding(flexRowDirection, ownerWidth)), + (node->getLeadingPadding(flexRowDirection, ownerWidth)).unwrap(), YGEdgeStart); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getTrailingPadding(flexRowDirection, ownerWidth)), + (node->getTrailingPadding(flexRowDirection, ownerWidth)).unwrap(), YGEdgeEnd); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getLeadingPadding(flexColumnDirection, ownerWidth)), + (node->getLeadingPadding(flexColumnDirection, ownerWidth)).unwrap(), YGEdgeTop); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getTrailingPadding(flexColumnDirection, ownerWidth)), + (node->getTrailingPadding(flexColumnDirection, ownerWidth)).unwrap(), YGEdgeBottom); if (node->getMeasure() != nullptr) { @@ -2832,8 +2835,8 @@ static void YGNodelayoutImpl( const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth; - const float leadingPaddingAndBorderCross = YGUnwrapFloatOptional( - node->getLeadingPaddingAndBorder(crossAxis, ownerWidth)); + const float leadingPaddingAndBorderCross = + (node->getLeadingPaddingAndBorder(crossAxis, ownerWidth)).unwrap(); const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); const float paddingAndBorderAxisCross = @@ -2849,26 +2852,30 @@ static void YGNodelayoutImpl( const float paddingAndBorderAxisColumn = isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + const float marginAxisRow = + (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); + const float marginAxisColumn = + (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); const float minInnerWidth = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) - + (YGResolveValue( + node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) + .unwrap() - paddingAndBorderAxisRow; const float maxInnerWidth = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - + (YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) + .unwrap() - paddingAndBorderAxisRow; const float minInnerHeight = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) - + (YGResolveValue( + node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) + .unwrap() - paddingAndBorderAxisColumn; const float maxInnerHeight = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) - + (YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) + .unwrap() - paddingAndBorderAxisColumn; const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; @@ -3079,11 +3086,11 @@ static void YGNodelayoutImpl( child->isLeadingPositionDefined(crossAxis); if (isChildLeadingPosDefined) { child->setLayoutPosition( - YGUnwrapFloatOptional(child->getLeadingPosition( - crossAxis, availableInnerCrossDim)) + + (child->getLeadingPosition(crossAxis, availableInnerCrossDim)) + .unwrap() + node->getLeadingBorder(crossAxis) + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + (child->getLeadingMargin(crossAxis, availableInnerWidth)) + .unwrap(), pos[crossAxis]); } // If leading position is not defined or calculations result in Nan, @@ -3092,8 +3099,8 @@ static void YGNodelayoutImpl( YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) { child->setLayoutPosition( node->getLeadingBorder(crossAxis) + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + (child->getLeadingMargin(crossAxis, availableInnerWidth)) + .unwrap(), pos[crossAxis]); } } else { @@ -3119,16 +3126,17 @@ static void YGNodelayoutImpl( child->getLayout().measuredDimensions[dim[mainAxis]]; float childCrossSize = !child->getStyle().aspectRatio.isUndefined() - ? ((YGUnwrapFloatOptional(child->getMarginForAxis( - crossAxis, availableInnerWidth)) + + ? (((child->getMarginForAxis(crossAxis, availableInnerWidth)) + .unwrap() + (isMainAxisRow ? childMainSize / child->getStyle().aspectRatio.unwrap() : childMainSize * child->getStyle().aspectRatio.unwrap()))) : collectedFlexItemsValues.crossDim; - childMainSize += YGUnwrapFloatOptional( - child->getMarginForAxis(mainAxis, availableInnerWidth)); + childMainSize += + (child->getMarginForAxis(mainAxis, availableInnerWidth)) + .unwrap(); YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly; @@ -3270,17 +3278,19 @@ static void YGNodelayoutImpl( lineHeight = YGFloatMax( lineHeight, child->getLayout().measuredDimensions[dim[crossAxis]] + - YGUnwrapFloatOptional(child->getMarginForAxis( - crossAxis, availableInnerWidth))); + (child->getMarginForAxis(crossAxis, availableInnerWidth)) + .unwrap()); } if (YGNodeAlignItem(node, child) == YGAlignBaseline) { const float ascent = YGBaseline(child) + - YGUnwrapFloatOptional(child->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth)); + (child->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth)) + .unwrap(); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional(child->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth)) - + (child->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth)) + .unwrap() - ascent; maxAscentForCurrentLine = YGFloatMax(maxAscentForCurrentLine, ascent); @@ -3305,16 +3315,18 @@ static void YGNodelayoutImpl( case YGAlignFlexStart: { child->setLayoutPosition( currentLead + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + (child->getLeadingMargin( + crossAxis, availableInnerWidth)) + .unwrap(), pos[crossAxis]); break; } case YGAlignFlexEnd: { child->setLayoutPosition( currentLead + lineHeight - - YGUnwrapFloatOptional(child->getTrailingMargin( - crossAxis, availableInnerWidth)) - + (child->getTrailingMargin( + crossAxis, availableInnerWidth)) + .unwrap() - child->getLayout().measuredDimensions[dim[crossAxis]], pos[crossAxis]); break; @@ -3331,8 +3343,9 @@ static void YGNodelayoutImpl( case YGAlignStretch: { child->setLayoutPosition( currentLead + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + (child->getLeadingMargin( + crossAxis, availableInnerWidth)) + .unwrap(), pos[crossAxis]); // Remeasure child with the line height as it as been only @@ -3342,15 +3355,17 @@ static void YGNodelayoutImpl( const float childWidth = isMainAxisRow ? (child->getLayout() .measuredDimensions[YGDimensionWidth] + - YGUnwrapFloatOptional(child->getMarginForAxis( - mainAxis, availableInnerWidth))) + (child->getMarginForAxis( + mainAxis, availableInnerWidth)) + .unwrap()) : lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout() .measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional(child->getMarginForAxis( - crossAxis, availableInnerWidth))) + (child->getMarginForAxis( + crossAxis, availableInnerWidth)) + .unwrap()) : lineHeight; if (!(YGFloatsEqual( @@ -3380,8 +3395,9 @@ static void YGNodelayoutImpl( case YGAlignBaseline: { child->setLayoutPosition( currentLead + maxAscentForCurrentLine - YGBaseline(child) + - YGUnwrapFloatOptional(child->getLeadingPosition( - YGFlexDirectionColumn, availableInnerCrossDim)), + (child->getLeadingPosition( + YGFlexDirectionColumn, availableInnerCrossDim)) + .unwrap(), YGEdgeTop); break; @@ -3437,8 +3453,9 @@ static void YGNodelayoutImpl( YGFloatMax( YGFloatMin( availableInnerMainDim + paddingAndBorderAxisMain, - YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - node, mainAxis, maxLineMainDim, mainAxisownerSize))), + (YGNodeBoundAxisWithinMinAndMax( + node, mainAxis, maxLineMainDim, mainAxisownerSize)) + .unwrap()), paddingAndBorderAxisMain), dim[mainAxis]); } @@ -3464,11 +3481,12 @@ static void YGNodelayoutImpl( YGFloatMax( YGFloatMin( availableInnerCrossDim + paddingAndBorderAxisCross, - YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - node, - crossAxis, - totalLineCrossDim + paddingAndBorderAxisCross, - crossAxisownerSize))), + (YGNodeBoundAxisWithinMinAndMax( + node, + crossAxis, + totalLineCrossDim + paddingAndBorderAxisCross, + crossAxisownerSize)) + .unwrap()), paddingAndBorderAxisCross), dim[crossAxis]); } @@ -3768,10 +3786,10 @@ bool YGLayoutNodeInternal( // expensive to measure, so it's worth avoiding redundant measurements if at // all possible. if (node->getMeasure() != nullptr) { - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + const float marginAxisRow = + (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); + const float marginAxisColumn = + (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); // First, try to use the layout cache. if (YGNodeCanUseCachedMeasurement( @@ -4071,16 +4089,18 @@ void YGNodeCalculateLayout( float width = YGUndefined; YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { - width = YGUnwrapFloatOptional( - YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + width = + (YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) + .unwrap(); widthMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue( node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth) .isUndefined()) { - width = YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)); + width = (YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) + .unwrap(); widthMeasureMode = YGMeasureModeAtMost; } else { width = ownerWidth; @@ -4091,18 +4111,20 @@ void YGNodeCalculateLayout( float height = YGUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { - height = YGUnwrapFloatOptional( - YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionColumn]), - ownerHeight) + - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + height = (YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionColumn]), + ownerHeight) + + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) + .unwrap(); heightMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue( node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight) .isUndefined()) { - height = YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)); + height = + (YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) + .unwrap(); heightMeasureMode = YGMeasureModeAtMost; } else { height = ownerHeight; -- 2.50.1.windows.1 From 5719132f5890e92573b203757298e1e17bc19734 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 19/53] `YGNodeBoundAxisWithinMinAndMax` accepts `YGFloatOptional` Summary: @public Saves some calls to `.unwrap()` Reviewed By: SidharthGuglani Differential Revision: D13209153 fbshipit-source-id: 5658586e91496085f39b3522db6364aaeafcfe2f --- yoga/Yoga.cpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index e000ab1d..b5320c63 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1209,7 +1209,7 @@ static inline bool YGNodeIsLayoutDimDefined( static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( const YGNodeRef node, const YGFlexDirection axis, - const float value, + const YGFloatOptional value, const float axisSize) { YGFloatOptional min; YGFloatOptional max; @@ -1226,15 +1226,15 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( node->getStyle().maxDimensions[YGDimensionWidth], axisSize); } - if (max >= YGFloatOptional{0} && YGFloatOptional{value} > max) { + if (max >= YGFloatOptional{0} && value > max) { return max; } - if (min >= YGFloatOptional{0} && YGFloatOptional{value} < min) { + if (min >= YGFloatOptional{0} && value < min) { return min; } - return YGFloatOptional{value}; + return value; } // Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't @@ -1246,7 +1246,9 @@ static inline float YGNodeBoundAxis( const float axisSize, const float widthSize) { return YGFloatMax( - (YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize)).unwrap(), + (YGNodeBoundAxisWithinMinAndMax( + node, axis, YGFloatOptional{value}, axisSize)) + .unwrap(), YGNodePaddingAndBorderForAxis(node, axis, widthSize)); } @@ -2014,7 +2016,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( (YGNodeBoundAxisWithinMinAndMax( child, mainAxis, - (child->getLayout().computedFlexBasis).unwrap(), + child->getLayout().computedFlexBasis, mainAxisownerSize)) .unwrap(); @@ -2089,13 +2091,12 @@ static float YGDistributeFreeSpaceSecondPass( const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - childFlexBasis = - (YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - (currentRelativeChild->getLayout().computedFlexBasis).unwrap(), - mainAxisownerSize)) - .unwrap(); + childFlexBasis = (YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + currentRelativeChild->getLayout().computedFlexBasis, + mainAxisownerSize)) + .unwrap(); float updatedMainSize = childFlexBasis; if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && @@ -2273,7 +2274,7 @@ static void YGDistributeFreeSpaceFirstPass( (YGNodeBoundAxisWithinMinAndMax( currentRelativeChild, mainAxis, - (currentRelativeChild->getLayout().computedFlexBasis).unwrap(), + currentRelativeChild->getLayout().computedFlexBasis, mainAxisownerSize)) .unwrap(); @@ -3454,7 +3455,10 @@ static void YGNodelayoutImpl( YGFloatMin( availableInnerMainDim + paddingAndBorderAxisMain, (YGNodeBoundAxisWithinMinAndMax( - node, mainAxis, maxLineMainDim, mainAxisownerSize)) + node, + mainAxis, + YGFloatOptional{maxLineMainDim}, + mainAxisownerSize)) .unwrap()), paddingAndBorderAxisMain), dim[mainAxis]); @@ -3484,7 +3488,8 @@ static void YGNodelayoutImpl( (YGNodeBoundAxisWithinMinAndMax( node, crossAxis, - totalLineCrossDim + paddingAndBorderAxisCross, + YGFloatOptional{totalLineCrossDim + + paddingAndBorderAxisCross}, crossAxisownerSize)) .unwrap()), paddingAndBorderAxisCross), -- 2.50.1.windows.1 From 5a65261a55c4cb87f1a3bd891f16ab30a2dfee0e Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 20/53] Remove templates for setting/getting style properties Summary: @public Replaces the `StyleProp` template with a simple setter macro / inlined getter code. The template was introduced to replace more extensive macros that would generate function signatures, too. Here, we keep the spirit of that change by only generating function bodies. Reviewed By: SidharthGuglani Differential Revision: D13233687 fbshipit-source-id: 218a7d5edb489b43a66c8c9d6156f74feefd2227 --- yoga/Yoga.cpp | 63 ++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index b5320c63..5a5da8b0 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -591,19 +591,6 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) { namespace { -template -struct StyleProp { - static T get(YGNodeRef node) { - return node->getStyle().*P; - } - static void set(YGNodeRef node, T newValue) { - if (node->getStyle().*P != newValue) { - node->getStyle().*P = newValue; - node->markDirtyAndPropogate(); - } - } -}; - struct Value { template static YGValue create(float value) { @@ -763,84 +750,88 @@ struct DimensionProp { return node->getLayout().instanceName[edge]; \ } -void YGNodeStyleSetDirection( - const YGNodeRef node, - const YGDirection direction) { - StyleProp::set(node, direction); +#define YG_NODE_STYLE_SET(node, property, value) \ + if (node->getStyle().property != value) { \ + node->getStyle().property = value; \ + node->markDirtyAndPropogate(); \ + } + +void YGNodeStyleSetDirection(const YGNodeRef node, const YGDirection value) { + YG_NODE_STYLE_SET(node, direction, value); } YGDirection YGNodeStyleGetDirection(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().direction; } void YGNodeStyleSetFlexDirection( const YGNodeRef node, const YGFlexDirection flexDirection) { - StyleProp::set(node, flexDirection); + YG_NODE_STYLE_SET(node, flexDirection, flexDirection); } YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().flexDirection; } void YGNodeStyleSetJustifyContent( const YGNodeRef node, const YGJustify justifyContent) { - StyleProp::set(node, justifyContent); + YG_NODE_STYLE_SET(node, justifyContent, justifyContent); } YGJustify YGNodeStyleGetJustifyContent(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().justifyContent; } void YGNodeStyleSetAlignContent( const YGNodeRef node, const YGAlign alignContent) { - StyleProp::set(node, alignContent); + YG_NODE_STYLE_SET(node, alignContent, alignContent); } YGAlign YGNodeStyleGetAlignContent(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().alignContent; } void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) { - StyleProp::set(node, alignItems); + YG_NODE_STYLE_SET(node, alignItems, alignItems); } YGAlign YGNodeStyleGetAlignItems(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().alignItems; } void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) { - StyleProp::set(node, alignSelf); + YG_NODE_STYLE_SET(node, alignSelf, alignSelf); } YGAlign YGNodeStyleGetAlignSelf(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().alignSelf; } void YGNodeStyleSetPositionType( const YGNodeRef node, const YGPositionType positionType) { - StyleProp::set(node, positionType); + YG_NODE_STYLE_SET(node, positionType, positionType); } YGPositionType YGNodeStyleGetPositionType(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().positionType; } void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) { - StyleProp::set(node, flexWrap); + YG_NODE_STYLE_SET(node, flexWrap, flexWrap); } YGWrap YGNodeStyleGetFlexWrap(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().flexWrap; } void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) { - StyleProp::set(node, overflow); + YG_NODE_STYLE_SET(node, overflow, overflow); } YGOverflow YGNodeStyleGetOverflow(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().overflow; } void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) { - StyleProp::set(node, display); + YG_NODE_STYLE_SET(node, display, display); } YGDisplay YGNodeStyleGetDisplay(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().display; } // TODO(T26792433): Change the API to accept YGFloatOptional. -- 2.50.1.windows.1 From 4248fd9d4cd4278679b11c6193e8cba84fe6389d Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 21/53] Use bitfields for enum members of `YGStyle` Summary: @public Puts all enum fields of `YGStyle` into bitfields. This saves 36 bytes (> 3%) per node. Reviewed By: SidharthGuglani Differential Revision: D13233686 fbshipit-source-id: 3ef7e0d6913f0254806acb942d9a9f5b78a5af9c --- yoga/YGStyle.h | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index c3a01d44..c4f7e3c7 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -30,16 +30,16 @@ constexpr std::array kYGDefaultDimensionValuesUnit = { struct YGStyle { using Dimensions = std::array; - YGDirection direction = YGDirectionInherit; - YGFlexDirection flexDirection = YGFlexDirectionColumn; - YGJustify justifyContent = YGJustifyFlexStart; - YGAlign alignContent = YGAlignFlexStart; - YGAlign alignItems = YGAlignStretch; - YGAlign alignSelf = YGAlignAuto; - YGPositionType positionType = YGPositionTypeRelative; - YGWrap flexWrap = YGWrapNoWrap; - YGOverflow overflow = YGOverflowVisible; - YGDisplay display = YGDisplayFlex; + YGDirection direction : 2; + YGFlexDirection flexDirection : 2; + YGJustify justifyContent : 3; + YGAlign alignContent : 3; + YGAlign alignItems : 3; + YGAlign alignSelf : 3; + YGPositionType positionType : 1; + YGWrap flexWrap : 2; + YGOverflow overflow : 2; + YGDisplay display : 1; YGFloatOptional flex = {}; YGFloatOptional flexGrow = {}; YGFloatOptional flexShrink = {}; @@ -54,7 +54,17 @@ struct YGStyle { // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio = {}; - YGStyle() = default; + YGStyle() + : direction(YGDirectionInherit), + flexDirection(YGFlexDirectionColumn), + justifyContent(YGJustifyFlexStart), + alignContent(YGAlignFlexStart), + alignItems(YGAlignStretch), + alignSelf(YGAlignAuto), + positionType(YGPositionTypeRelative), + flexWrap(YGWrapNoWrap), + overflow(YGOverflowVisible), + display(YGDisplayFlex) {} bool operator==(const YGStyle& style); bool operator!=(YGStyle style) { -- 2.50.1.windows.1 From 6b7f6980f939fa2702b313b5d9d17eced83e7fcb Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 6 Dec 2018 07:35:10 -0800 Subject: [PATCH 22/53] Don't pass `std::string` by pointer Summary: @public Pass strings by mutable ref rather than pointer. Reviewed By: SidharthGuglani Differential Revision: D13236159 fbshipit-source-id: 04fd35e8a9e106ba8cdd71cfab31e8d90edaac9e --- yoga/YGNodePrint.cpp | 26 +++++++++++++------------- yoga/YGNodePrint.h | 2 +- yoga/Yoga.cpp | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index c497996e..753a00b6 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -14,9 +14,9 @@ namespace facebook { namespace yoga { typedef std::string string; -static void indent(string* base, uint32_t level) { +static void indent(string& base, uint32_t level) { for (uint32_t i = 0; i < level; ++i) { - base->append(" "); + base.append(" "); } } @@ -25,7 +25,7 @@ static bool areFourValuesEqual(const std::array& four) { YGValueEqual(four[0], four[3]); } -static void appendFormatedString(string* str, const char* fmt, ...) { +static void appendFormatedString(string& str, const char* fmt, ...) { va_list args; va_start(args, fmt); va_list argsCopy; @@ -35,11 +35,11 @@ static void appendFormatedString(string* str, const char* fmt, ...) { vsnprintf(buf.data(), buf.size(), fmt, argsCopy); va_end(argsCopy); string result = string(buf.begin(), buf.end() - 1); - str->append(result); + str.append(result); } static void appendFloatOptionalIfDefined( - string* base, + string& base, const string key, const YGFloatOptional num) { if (!num.isUndefined()) { @@ -48,12 +48,12 @@ static void appendFloatOptionalIfDefined( } static void appendNumberIfNotUndefined( - string* base, + string& base, const string key, const YGValue number) { if (number.unit != YGUnitUndefined) { if (number.unit == YGUnitAuto) { - base->append(key + ": auto; "); + base.append(key + ": auto; "); } else { string unit = number.unit == YGUnitPoint ? "px" : "%%"; appendFormatedString( @@ -63,23 +63,23 @@ static void appendNumberIfNotUndefined( } static void -appendNumberIfNotAuto(string* base, const string& key, const YGValue number) { +appendNumberIfNotAuto(string& base, const string& key, const YGValue number) { if (number.unit != YGUnitAuto) { appendNumberIfNotUndefined(base, key, number); } } static void -appendNumberIfNotZero(string* base, const string& str, const YGValue number) { +appendNumberIfNotZero(string& base, const string& str, const YGValue number) { if (number.unit == YGUnitAuto) { - base->append(str + ": auto; "); + base.append(str + ": auto; "); } else if (!YGFloatsEqual(number.value, 0)) { appendNumberIfNotUndefined(base, str, number); } } static void appendEdges( - string* base, + string& base, const string& key, const std::array& edges) { if (areFourValuesEqual(edges)) { @@ -93,7 +93,7 @@ static void appendEdges( } static void appendEdgeIfNotUndefined( - string* base, + string& base, const string& str, const std::array& edges, const YGEdge edge) { @@ -102,7 +102,7 @@ static void appendEdgeIfNotUndefined( } void YGNodeToString( - std::string* str, + std::string& str, YGNodeRef node, YGPrintOptions options, uint32_t level) { diff --git a/yoga/YGNodePrint.h b/yoga/YGNodePrint.h index 9d36ba8d..9615bf8e 100644 --- a/yoga/YGNodePrint.h +++ b/yoga/YGNodePrint.h @@ -13,7 +13,7 @@ namespace facebook { namespace yoga { void YGNodeToString( - std::string* str, + std::string& str, YGNodeRef node, YGPrintOptions options, uint32_t level); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 5a5da8b0..f0327f87 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1057,7 +1057,7 @@ static void YGNodePrintInternal( const YGNodeRef node, const YGPrintOptions options) { std::string str; - facebook::yoga::YGNodeToString(&str, node, options, 0); + facebook::yoga::YGNodeToString(str, node, options, 0); YGLog(node, YGLogLevelDebug, str.c_str()); } -- 2.50.1.windows.1 From b26e637c815aa74d8772305c531b9ff18b2f08e7 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 7 Dec 2018 12:37:12 -0800 Subject: [PATCH 23/53] Back out Stack D13119110..D13236159 Summary: backout, causes failures Reviewed By: adityasharat Differential Revision: D13376210 fbshipit-source-id: 1fa8823f2dce601c47738f34ddb2674288197e79 --- csharp/Facebook.Yoga/YogaConstants.cs | 23 +- java/com/facebook/yoga/YogaConstants.java | 30 +- tests/YGFloatOptionalTest.cpp | 205 -------- tools/build_defs/oss/yoga_defs.bzl | 1 + yoga/Utils.cpp | 15 +- yoga/Utils.h | 36 +- yoga/YGFloatOptional.cpp | 83 ++++ yoga/YGFloatOptional.h | 78 +-- yoga/YGNode.cpp | 65 ++- yoga/YGNode.h | 2 +- yoga/YGNodePrint.cpp | 29 +- yoga/YGNodePrint.h | 2 +- yoga/YGStyle.cpp | 37 +- yoga/YGStyle.h | 32 +- yoga/YGValue.cpp | 11 - yoga/YGValue.h | 56 --- yoga/Yoga-internal.h | 10 +- yoga/Yoga.cpp | 569 +++++++++++----------- yoga/Yoga.h | 29 +- 19 files changed, 612 insertions(+), 701 deletions(-) delete mode 100644 tests/YGFloatOptionalTest.cpp create mode 100644 yoga/YGFloatOptional.cpp delete mode 100644 yoga/YGValue.cpp delete mode 100644 yoga/YGValue.h diff --git a/csharp/Facebook.Yoga/YogaConstants.cs b/csharp/Facebook.Yoga/YogaConstants.cs index 9e05cca3..a715b43c 100644 --- a/csharp/Facebook.Yoga/YogaConstants.cs +++ b/csharp/Facebook.Yoga/YogaConstants.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -9,11 +9,28 @@ namespace Facebook.Yoga { public static class YogaConstants { - public const float Undefined = float.NaN; + /** + * Large positive number signifies that the property(float) is undefined. Earlier we used to have + * YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as + * it assumes all floating-point calculation involve and result into finite numbers. For more + * information regarding -ffast-math compiler flag in clang, have a look at + * https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math + */ + public const float Undefined = 10E20F; public static bool IsUndefined(float value) { - return float.IsNaN(value); + // Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN, + // the benefit of which + // was that if NAN is involved in any mathematical expression the result was NAN. But since we + // want to have `-ffast-math` + // flag being used by compiler which assumes that the floating point values are not NAN and Inf, + // we represent YGUndefined as 10.1E20. + // But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would + // change. + // So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it + // is undefined. + return value >= 10E8F || value <= -10E8; } public static bool IsUndefined(YogaValue value) diff --git a/java/com/facebook/yoga/YogaConstants.java b/java/com/facebook/yoga/YogaConstants.java index b04a7e53..61e212ef 100644 --- a/java/com/facebook/yoga/YogaConstants.java +++ b/java/com/facebook/yoga/YogaConstants.java @@ -1,17 +1,35 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. */ package com.facebook.yoga; public class YogaConstants { - public static final float UNDEFINED = Float.NaN; + /** + * Large positive number signifies that the property(float) is undefined. Earlier we used to have + * YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as + * it assumes all floating-point calculation involve and result into finite numbers. For more + * information regarding -ffast-math compiler flag in clang, have a look at + * https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math + */ + public static final float UNDEFINED = (float) (10E20); public static boolean isUndefined(float value) { - return Float.compare(value, UNDEFINED) == 0; + // Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN, + // the benefit of which + // was that if NAN is involved in any mathematical expression the result was NAN. But since we + // want to have `-ffast-math` + // flag being used by compiler which assumes that the floating point values are not NAN and Inf, + // we represent YGUndefined as 10.1E20. + // But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would + // change. + // So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it + // is undefined. + return (Float.compare(value, (float) 10E8) >= 0 || Float.compare(value, (float) -10E8) <= 0); } public static boolean isUndefined(YogaValue value) { diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp deleted file mode 100644 index cb4a35a7..00000000 --- a/tests/YGFloatOptionalTest.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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 -#include - -constexpr auto empty = YGFloatOptional{}; -constexpr auto zero = YGFloatOptional{0.0f}; -constexpr auto one = YGFloatOptional{1.0f}; -constexpr auto positive = YGFloatOptional{1234.5f}; -constexpr auto negative = YGFloatOptional{-9876.5f}; - -TEST(YGFloatOptional, value) { - ASSERT_EQ(zero.unwrap(), 0.0f); - ASSERT_EQ(positive.unwrap(), 1234.5f); - ASSERT_EQ(negative.unwrap(), -9876.5f); - ASSERT_TRUE(YGFloatIsUndefined(empty.unwrap())); - - ASSERT_TRUE(empty.isUndefined()); - ASSERT_FALSE(zero.isUndefined()); - ASSERT_FALSE(negative.isUndefined()); -} - -TEST(YGFloatOptional, equality) { - ASSERT_TRUE(empty == empty); - ASSERT_TRUE(empty == YGUndefined); - ASSERT_FALSE(empty == zero); - ASSERT_FALSE(empty == negative); - ASSERT_FALSE(empty == 12.3f); - - ASSERT_TRUE(zero == zero); - ASSERT_TRUE(zero == 0.0f); - ASSERT_FALSE(zero == positive); - ASSERT_FALSE(zero == -5555.5f); - - ASSERT_TRUE(one == one); - ASSERT_TRUE(one == 1.0f); - ASSERT_FALSE(one == positive); - - ASSERT_TRUE(negative == negative); - ASSERT_TRUE(negative == negative.unwrap()); - ASSERT_FALSE(negative == zero); -} - -TEST(YGFloatOptional, inequality) { - ASSERT_FALSE(empty != empty); - ASSERT_FALSE(empty != YGUndefined); - ASSERT_TRUE(empty != zero); - ASSERT_TRUE(empty != negative); - ASSERT_TRUE(empty != 12.3f); - - ASSERT_FALSE(zero != zero); - ASSERT_FALSE(zero != 0.0f); - ASSERT_TRUE(zero != positive); - ASSERT_TRUE(zero != -5555.5f); - - ASSERT_FALSE(one != one); - ASSERT_FALSE(one != 1.0f); - ASSERT_TRUE(one != positive); - - ASSERT_FALSE(negative != negative); - ASSERT_FALSE(negative != negative.unwrap()); - ASSERT_TRUE(negative != zero); -} - -TEST(YGFloatOptional, greater) { - ASSERT_FALSE(empty > empty); - ASSERT_FALSE(empty > zero); - ASSERT_FALSE(empty > one); - ASSERT_FALSE(empty > positive); - ASSERT_FALSE(empty > negative); - ASSERT_FALSE(zero > empty); - ASSERT_FALSE(one > empty); - ASSERT_FALSE(positive > empty); - ASSERT_FALSE(negative > empty); - - ASSERT_TRUE(zero > negative); - ASSERT_FALSE(zero > zero); - ASSERT_FALSE(zero > positive); - ASSERT_FALSE(zero > one); - - ASSERT_TRUE(one > negative); - ASSERT_TRUE(one > zero); - ASSERT_FALSE(one > empty); - ASSERT_FALSE(one > positive); - - ASSERT_TRUE(negative > YGFloatOptional{-INFINITY}); - ASSERT_FALSE(negative > empty); -} - -TEST(YGFloatOptional, lower) { - ASSERT_FALSE(empty < empty); - ASSERT_FALSE(empty < zero); - ASSERT_FALSE(empty < one); - ASSERT_FALSE(empty < positive); - ASSERT_FALSE(empty < negative); - ASSERT_FALSE(zero < empty); - ASSERT_FALSE(one < empty); - ASSERT_FALSE(positive < empty); - ASSERT_FALSE(negative < empty); - - ASSERT_TRUE(negative < zero); - ASSERT_FALSE(zero < zero); - ASSERT_FALSE(positive < zero); - ASSERT_FALSE(one < zero); - - ASSERT_TRUE(negative < one); - ASSERT_TRUE(zero < one); - ASSERT_FALSE(empty < one); - ASSERT_FALSE(positive < one); - - ASSERT_TRUE(YGFloatOptional{-INFINITY} < negative); - ASSERT_FALSE(empty < negative); -} - -TEST(YGFloatOptional, greater_equals) { - ASSERT_TRUE(empty >= empty); - ASSERT_FALSE(empty >= zero); - ASSERT_FALSE(empty >= one); - ASSERT_FALSE(empty >= positive); - ASSERT_FALSE(empty >= negative); - - ASSERT_TRUE(zero >= negative); - ASSERT_TRUE(zero >= zero); - ASSERT_FALSE(zero >= positive); - ASSERT_FALSE(zero >= one); - - ASSERT_TRUE(one >= negative); - ASSERT_TRUE(one >= zero); - ASSERT_FALSE(one >= empty); - ASSERT_FALSE(one >= positive); - - ASSERT_TRUE(negative >= YGFloatOptional{-INFINITY}); - ASSERT_TRUE(negative >= negative); - ASSERT_FALSE(negative >= empty); -} - -TEST(YGFloatOptional, lower_equals) { - ASSERT_TRUE(empty <= empty); - ASSERT_FALSE(zero <= empty); - ASSERT_FALSE(one <= empty); - ASSERT_FALSE(positive <= empty); - ASSERT_FALSE(negative <= empty); - - ASSERT_TRUE(negative <= zero); - ASSERT_TRUE(zero <= zero); - ASSERT_FALSE(positive <= zero); - ASSERT_FALSE(one <= zero); - - ASSERT_TRUE(negative <= one); - ASSERT_TRUE(zero <= one); - ASSERT_FALSE(empty <= one); - ASSERT_FALSE(positive <= one); - - ASSERT_TRUE(YGFloatOptional{-INFINITY} <= negative); - ASSERT_TRUE(negative <= negative); - ASSERT_FALSE(empty <= negative); -} - -TEST(YGFloatOptional, addition) { - ASSERT_EQ(zero + one, one); - ASSERT_EQ( - negative + positive, - YGFloatOptional{negative.unwrap() + positive.unwrap()}); - ASSERT_EQ(empty + zero, empty); - ASSERT_EQ(empty + empty, empty); - ASSERT_EQ(negative + empty, empty); -} - -TEST(YGFloatOptional, subtraction) { - ASSERT_EQ(zero - one, YGFloatOptional{-1.0f}); - ASSERT_EQ( - negative - positive, - YGFloatOptional{negative.unwrap() - positive.unwrap()}); - ASSERT_EQ(empty - zero, empty); - ASSERT_EQ(empty - empty, empty); - ASSERT_EQ(negative - empty, empty); -} - -TEST(YGFloatOptional, unary_minus) { - ASSERT_EQ(-zero, zero); - ASSERT_EQ(-negative, YGFloatOptional{-negative.unwrap()}); - ASSERT_EQ(-positive, YGFloatOptional{-positive.unwrap()}); - ASSERT_EQ(-empty, empty); -} - -TEST(YGFloatOptional, orElse) { - ASSERT_EQ(empty.orElse(1.23f), 1.23f); - ASSERT_TRUE(YGFloatIsUndefined(empty.orElse(YGUndefined))); - ASSERT_EQ(one.orElse(1.23f), 1.0f); -} - -TEST(YGFloatOptional, orElseGet) { - auto x = empty.orElseGet([] { return 1.23f; }); - ASSERT_EQ(x, 1.23f); - ASSERT_TRUE(YGFloatIsUndefined(empty.orElseGet([] { return YGUndefined; }))); - - auto y = one.orElseGet([] { return 1.23f; }); - ASSERT_EQ(y, 1.0f); -} diff --git a/tools/build_defs/oss/yoga_defs.bzl b/tools/build_defs/oss/yoga_defs.bzl index 5a5872fe..7eca7b9b 100644 --- a/tools/build_defs/oss/yoga_defs.bzl +++ b/tools/build_defs/oss/yoga_defs.bzl @@ -58,6 +58,7 @@ BASE_COMPILER_FLAGS = [ "-Wall", "-Werror", "-O3", + "-ffast-math", ] LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [ diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index b246f943..74cc38c9 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -55,14 +55,15 @@ float YGFloatSanitize(const float val) { return yoga::isUndefined(val) ? 0 : val; } +float YGUnwrapFloatOptional(const YGFloatOptional& op) { + return op.isUndefined() ? YGUndefined : op.getValue(); +} + YGFloatOptional YGFloatOptionalMax( - const YGFloatOptional op1, - const YGFloatOptional op2) { - if (op1 > op2) { - return op1; - } - if (op2 > op1) { - return op2; + const YGFloatOptional& op1, + const YGFloatOptional& op2) { + if (!op1.isUndefined() && !op2.isUndefined()) { + return op1.getValue() > op2.getValue() ? op1 : op2; } return op1.isUndefined() ? op2 : op1; } diff --git a/yoga/Utils.h b/yoga/Utils.h index a0d49235..d578511c 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -57,12 +57,22 @@ bool YGValueEqual(const YGValue a, const YGValue b); // difference between two floats is less than 0.0001f or both are undefined. bool YGFloatsEqual(const float a, const float b); +// We need custom max function, since we want that, if one argument is +// YGUndefined then the max funtion should return the other argument as the max +// value. We wouldn't have needed a custom max function if YGUndefined was NAN +// as fmax has the same behaviour, but with NAN we cannot use `-ffast-math` +// compiler flag. float YGFloatMax(const float a, const float b); YGFloatOptional YGFloatOptionalMax( - const YGFloatOptional op1, - const YGFloatOptional op2); + const YGFloatOptional& op1, + const YGFloatOptional& op2); +// We need custom min function, since we want that, if one argument is +// YGUndefined then the min funtion should return the other argument as the min +// value. We wouldn't have needed a custom min function if YGUndefined was NAN +// as fmin has the same behaviour, but with NAN we cannot use `-ffast-math` +// compiler flag. float YGFloatMin(const float a, const float b); // This custom float comparision function compares the array of float with @@ -82,6 +92,11 @@ bool YGFloatArrayEqual( // This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise float YGFloatSanitize(const float val); +// This function unwraps optional and returns YGUndefined if not defined or +// op.value otherwise +// TODO: Get rid off this function +float YGUnwrapFloatOptional(const YGFloatOptional& op); + YGFlexDirection YGFlexDirectionCross( const YGFlexDirection flexDirection, const YGDirection direction); @@ -91,17 +106,18 @@ inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { flexDirection == YGFlexDirectionRowReverse; } -inline YGFloatOptional YGResolveValue( - const YGValue value, - const float ownerSize) { +inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) { switch (value.unit) { + case YGUnitUndefined: + case YGUnitAuto: + return YGFloatOptional(); case YGUnitPoint: - return YGFloatOptional{value.value}; + return YGFloatOptional(value.value); case YGUnitPercent: - return YGFloatOptional{value.value * ownerSize * 0.01f}; - default: - return YGFloatOptional{}; + return YGFloatOptional( + static_cast(value.value * ownerSize * 0.01)); } + return YGFloatOptional(); } inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { @@ -123,7 +139,7 @@ inline YGFlexDirection YGResolveFlexDirection( return flexDirection; } -inline YGFloatOptional YGResolveValueMargin( +static inline YGFloatOptional YGResolveValueMargin( const YGValue value, const float ownerSize) { return value.unit == YGUnitAuto ? YGFloatOptional(0) diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp new file mode 100644 index 00000000..d023dccb --- /dev/null +++ b/yoga/YGFloatOptional.cpp @@ -0,0 +1,83 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + */ +#include "YGFloatOptional.h" +#include +#include +#include "Yoga.h" +#include "Yoga-internal.h" + +using namespace facebook; + +YGFloatOptional::YGFloatOptional(float value) { + if (yoga::isUndefined(value)) { + isUndefined_ = true; + value_ = 0; + } else { + value_ = value; + isUndefined_ = false; + } +} + +float YGFloatOptional::getValue() const { + if (isUndefined_) { + // Abort, accessing a value of an undefined float optional + std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; + std::exit(EXIT_FAILURE); + } + return value_; +} + +bool YGFloatOptional::operator==(const YGFloatOptional& op) const { + if (isUndefined_ == op.isUndefined()) { + return isUndefined_ || value_ == op.getValue(); + } + return false; +} + +bool YGFloatOptional::operator!=(const YGFloatOptional& op) const { + return !(*this == op); +} + +bool YGFloatOptional::operator==(float val) const { + if (yoga::isUndefined(val) == isUndefined_) { + return isUndefined_ || val == value_; + } + return false; +} + +bool YGFloatOptional::operator!=(float val) const { + return !(*this == val); +} + +YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) { + if (!isUndefined_ && !op.isUndefined_) { + return YGFloatOptional(value_ + op.value_); + } + return YGFloatOptional(); +} + +bool YGFloatOptional::operator>(const YGFloatOptional& op) const { + if (isUndefined_ || op.isUndefined_) { + return false; + } + return value_ > op.value_; +} + +bool YGFloatOptional::operator<(const YGFloatOptional& op) const { + if (isUndefined_ || op.isUndefined_) { + return false; + } + return value_ < op.value_; +} + +bool YGFloatOptional::operator>=(const YGFloatOptional& op) const { + return *this == op || *this > op; +} + +bool YGFloatOptional::operator<=(const YGFloatOptional& op) const { + return *this == op || *this < op; +} diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 3dd3d5c9..07fbb64b 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -6,68 +6,38 @@ */ #pragma once -#include -#include "Yoga-internal.h" - struct YGFloatOptional { private: - float value_ = std::numeric_limits::quiet_NaN(); + float value_ = 0; + bool isUndefined_ = true; public: - explicit constexpr YGFloatOptional(float value) : value_(value) {} - constexpr YGFloatOptional() = default; + explicit YGFloatOptional(float value); + YGFloatOptional() = default; - // returns the wrapped value, or a value x with YGIsUndefined(x) == true - constexpr float unwrap() const { - return value_; + // Program will terminate if the value of an undefined is accessed. Please + // make sure to check if the optional is defined before calling this function. + // To check if float optional is defined, use `isUndefined()`. + float getValue() const; + + // Sets the value of float optional, and thus isUndefined is assigned false. + void setValue(float val) { + value_ = val; + isUndefined_ = false; } - constexpr bool isUndefined() const { - // std::isnan is not constexpr - return !(value_ == value_); + bool isUndefined() const { + return isUndefined_; } - constexpr float orElse(float other) const { - return isUndefined() ? other : value_; - } + YGFloatOptional operator+(const YGFloatOptional& op); + bool operator>(const YGFloatOptional& op) const; + bool operator<(const YGFloatOptional& op) const; + bool operator>=(const YGFloatOptional& op) const; + bool operator<=(const YGFloatOptional& op) const; + bool operator==(const YGFloatOptional& op) const; + bool operator!=(const YGFloatOptional& op) const; - template - constexpr float orElseGet(Factory&& f) const { - return isUndefined() ? f() : value_; - } - - YGFloatOptional operator-() const { - return YGFloatOptional{-value_}; - } - YGFloatOptional operator+(YGFloatOptional op) const { - return YGFloatOptional{value_ + op.value_}; - } - YGFloatOptional operator-(YGFloatOptional op) const { - return YGFloatOptional{value_ - op.value_}; - } - bool operator>(YGFloatOptional op) const { - return value_ > op.value_; - } - bool operator<(YGFloatOptional op) const { - return value_ < op.value_; - } - bool operator>=(YGFloatOptional op) const { - return *this > op || *this == op; - } - bool operator<=(YGFloatOptional op) const { - return *this < op || *this == op; - } - bool operator==(YGFloatOptional op) const { - return value_ == op.value_ || (isUndefined() && op.isUndefined()); - } - bool operator!=(YGFloatOptional op) const { - return !(*this == op); - } - - bool operator==(float val) const { - return value_ == val || (isUndefined() && yoga::isUndefined(val)); - } - bool operator!=(float val) const { - return !(*this == val); - } + bool operator==(float val) const; + bool operator!=(float val) const; }; diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 9ae03b01..1694692c 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -175,7 +175,7 @@ void YGNode::setLayoutLastOwnerDirection(YGDirection direction) { } void YGNode::setLayoutComputedFlexBasis( - const YGFloatOptional computedFlexBasis) { + const YGFloatOptional& computedFlexBasis) { layout_.computedFlexBasis = computedFlexBasis; } @@ -209,7 +209,11 @@ YGFloatOptional YGNode::relativePosition( return getLeadingPosition(axis, axisSize); } - return -getTrailingPosition(axis, axisSize); + YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize); + if (!trailingPosition.isUndefined()) { + trailingPosition.setValue(-1 * trailingPosition.getValue()); + } + return trailingPosition; } void YGNode::setPosition( @@ -232,18 +236,20 @@ void YGNode::setPosition( relativePosition(crossAxis, crossSize); setLayoutPosition( - (getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), + YGUnwrapFloatOptional( + getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain), leading[mainAxis]); setLayoutPosition( - (getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), + YGUnwrapFloatOptional( + getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain), trailing[mainAxis]); setLayoutPosition( - (getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross) - .unwrap(), + YGUnwrapFloatOptional( + getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross), leading[crossAxis]); setLayoutPosition( - (getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross) - .unwrap(), + YGUnwrapFloatOptional( + getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross), trailing[crossAxis]); } @@ -298,7 +304,7 @@ YGValue YGNode::resolveFlexBasisPtr() const { if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) { return flexBasis; } - if (style_.flex > YGFloatOptional{0.0f}) { + if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { return config_->useWebDefaults ? YGValueAuto : YGValueZero; } return YGValueAuto; @@ -388,23 +394,27 @@ float YGNode::resolveFlexGrow() { if (owner_ == nullptr) { return 0.0; } - - return style_.flexGrow.orElseGet( - [this] { return style_.flex.orElse(kDefaultFlexGrow); }); + if (!style_.flexGrow.isUndefined()) { + return style_.flexGrow.getValue(); + } + if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { + return style_.flex.getValue(); + } + return kDefaultFlexGrow; } float YGNode::resolveFlexShrink() { if (owner_ == nullptr) { return 0.0; } - return style_.flexShrink.orElseGet([this] { - if (style_.flex < YGFloatOptional{0.0f} && !config_->useWebDefaults) { - return -style_.flex.unwrap(); - } else { - return config_->useWebDefaults ? kWebDefaultFlexShrink - : kDefaultFlexShrink; - } - }); + if (!style_.flexShrink.isUndefined()) { + return style_.flexShrink.getValue(); + } + if (!config_->useWebDefaults && !style_.flex.isUndefined() && + style_.flex.getValue() < 0.0f) { + return -style_.flex.getValue(); + } + return config_->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink; } bool YGNode::isNodeFlexible() { @@ -443,9 +453,11 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const { YGFloatOptional YGNode::getLeadingPadding( const YGFlexDirection axis, const float widthSize) const { - const YGFloatOptional paddingEdgeStart = + const YGFloatOptional& paddingEdgeStart = YGResolveValue(style_.padding[YGEdgeStart], widthSize); - if (YGFlexDirectionIsRow(axis) && paddingEdgeStart >= YGFloatOptional{0.0f}) { + if (YGFlexDirectionIsRow(axis) && + style_.padding[YGEdgeStart].unit != YGUnitUndefined && + !paddingEdgeStart.isUndefined() && paddingEdgeStart.getValue() >= 0.0f) { return paddingEdgeStart; } @@ -458,10 +470,11 @@ YGFloatOptional YGNode::getLeadingPadding( YGFloatOptional YGNode::getTrailingPadding( const YGFlexDirection axis, const float widthSize) const { - const YGFloatOptional paddingEdgeEnd = - YGResolveValue(style_.padding[YGEdgeEnd], widthSize); - if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) { - return paddingEdgeEnd; + if (YGFlexDirectionIsRow(axis) && + style_.padding[YGEdgeEnd].unit != YGUnitUndefined && + !YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() && + YGResolveValue(style_.padding[YGEdgeEnd], widthSize).getValue() >= 0.0f) { + return YGResolveValue(style_.padding[YGEdgeEnd], widthSize); } YGFloatOptional resolvedValue = YGResolveValue( diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 57312812..719eb2ea 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -235,7 +235,7 @@ struct YGNode { void setDirty(bool isDirty); void setLayoutLastOwnerDirection(YGDirection direction); - void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis); + void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis); void setLayoutComputedFlexBasisGeneration( uint32_t computedFlexBasisGeneration); void setLayoutMeasuredDimension(float measuredDimension, int index); diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 753a00b6..541a6fef 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -14,9 +14,9 @@ namespace facebook { namespace yoga { typedef std::string string; -static void indent(string& base, uint32_t level) { +static void indent(string* base, uint32_t level) { for (uint32_t i = 0; i < level; ++i) { - base.append(" "); + base->append(" "); } } @@ -25,7 +25,7 @@ static bool areFourValuesEqual(const std::array& four) { YGValueEqual(four[0], four[3]); } -static void appendFormatedString(string& str, const char* fmt, ...) { +static void appendFormatedString(string* str, const char* fmt, ...) { va_list args; va_start(args, fmt); va_list argsCopy; @@ -35,25 +35,25 @@ static void appendFormatedString(string& str, const char* fmt, ...) { vsnprintf(buf.data(), buf.size(), fmt, argsCopy); va_end(argsCopy); string result = string(buf.begin(), buf.end() - 1); - str.append(result); + str->append(result); } static void appendFloatOptionalIfDefined( - string& base, + string* base, const string key, const YGFloatOptional num) { if (!num.isUndefined()) { - appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap()); + appendFormatedString(base, "%s: %g; ", key.c_str(), num.getValue()); } } static void appendNumberIfNotUndefined( - string& base, + string* base, const string key, const YGValue number) { if (number.unit != YGUnitUndefined) { if (number.unit == YGUnitAuto) { - base.append(key + ": auto; "); + base->append(key + ": auto; "); } else { string unit = number.unit == YGUnitPoint ? "px" : "%%"; appendFormatedString( @@ -63,23 +63,24 @@ static void appendNumberIfNotUndefined( } static void -appendNumberIfNotAuto(string& base, const string& key, const YGValue number) { +appendNumberIfNotAuto(string* base, const string& key, const YGValue number) { if (number.unit != YGUnitAuto) { appendNumberIfNotUndefined(base, key, number); } } static void -appendNumberIfNotZero(string& base, const string& str, const YGValue number) { +appendNumberIfNotZero(string* base, const string& str, const YGValue number) { + if (number.unit == YGUnitAuto) { - base.append(str + ": auto; "); + base->append(str + ": auto; "); } else if (!YGFloatsEqual(number.value, 0)) { appendNumberIfNotUndefined(base, str, number); } } static void appendEdges( - string& base, + string* base, const string& key, const std::array& edges) { if (areFourValuesEqual(edges)) { @@ -93,7 +94,7 @@ static void appendEdges( } static void appendEdgeIfNotUndefined( - string& base, + string* base, const string& str, const std::array& edges, const YGEdge edge) { @@ -102,7 +103,7 @@ static void appendEdgeIfNotUndefined( } void YGNodeToString( - std::string& str, + std::string* str, YGNodeRef node, YGPrintOptions options, uint32_t level) { diff --git a/yoga/YGNodePrint.h b/yoga/YGNodePrint.h index 9615bf8e..9d36ba8d 100644 --- a/yoga/YGNodePrint.h +++ b/yoga/YGNodePrint.h @@ -13,7 +13,7 @@ namespace facebook { namespace yoga { void YGNodeToString( - std::string& str, + std::string* str, YGNodeRef node, YGPrintOptions options, uint32_t level); diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp index a2f4a17e..bc90463e 100644 --- a/yoga/YGStyle.cpp +++ b/yoga/YGStyle.cpp @@ -8,8 +8,8 @@ // Yoga specific properties, not compatible with flexbox specification bool YGStyle::operator==(const YGStyle& style) { - return ( - direction == style.direction && flexDirection == style.flexDirection && + bool areNonFloatValuesEqual = direction == style.direction && + flexDirection == style.flexDirection && justifyContent == style.justifyContent && alignContent == style.alignContent && alignItems == style.alignItems && alignSelf == style.alignSelf && positionType == style.positionType && @@ -21,7 +21,34 @@ bool YGStyle::operator==(const YGStyle& style) { YGValueArrayEqual(border, style.border) && YGValueArrayEqual(dimensions, style.dimensions) && YGValueArrayEqual(minDimensions, style.minDimensions) && - YGValueArrayEqual(maxDimensions, style.maxDimensions) && - flex == style.flex && flexGrow == style.flexGrow && - flexShrink == style.flexShrink && aspectRatio == style.aspectRatio); + YGValueArrayEqual(maxDimensions, style.maxDimensions); + + areNonFloatValuesEqual = + areNonFloatValuesEqual && flex.isUndefined() == style.flex.isUndefined(); + if (areNonFloatValuesEqual && !flex.isUndefined() && + !style.flex.isUndefined()) { + areNonFloatValuesEqual = + areNonFloatValuesEqual && flex.getValue() == style.flex.getValue(); + } + + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexGrow.isUndefined() == style.flexGrow.isUndefined(); + if (areNonFloatValuesEqual && !flexGrow.isUndefined()) { + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexGrow.getValue() == style.flexGrow.getValue(); + } + + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexShrink.isUndefined() == style.flexShrink.isUndefined(); + if (areNonFloatValuesEqual && !style.flexShrink.isUndefined()) { + areNonFloatValuesEqual = areNonFloatValuesEqual && + flexShrink.getValue() == style.flexShrink.getValue(); + } + + if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) { + areNonFloatValuesEqual = areNonFloatValuesEqual && + aspectRatio.getValue() == style.aspectRatio.getValue(); + } + + return areNonFloatValuesEqual; } diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index c4f7e3c7..c3a01d44 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -30,16 +30,16 @@ constexpr std::array kYGDefaultDimensionValuesUnit = { struct YGStyle { using Dimensions = std::array; - YGDirection direction : 2; - YGFlexDirection flexDirection : 2; - YGJustify justifyContent : 3; - YGAlign alignContent : 3; - YGAlign alignItems : 3; - YGAlign alignSelf : 3; - YGPositionType positionType : 1; - YGWrap flexWrap : 2; - YGOverflow overflow : 2; - YGDisplay display : 1; + YGDirection direction = YGDirectionInherit; + YGFlexDirection flexDirection = YGFlexDirectionColumn; + YGJustify justifyContent = YGJustifyFlexStart; + YGAlign alignContent = YGAlignFlexStart; + YGAlign alignItems = YGAlignStretch; + YGAlign alignSelf = YGAlignAuto; + YGPositionType positionType = YGPositionTypeRelative; + YGWrap flexWrap = YGWrapNoWrap; + YGOverflow overflow = YGOverflowVisible; + YGDisplay display = YGDisplayFlex; YGFloatOptional flex = {}; YGFloatOptional flexGrow = {}; YGFloatOptional flexShrink = {}; @@ -54,17 +54,7 @@ struct YGStyle { // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio = {}; - YGStyle() - : direction(YGDirectionInherit), - flexDirection(YGFlexDirectionColumn), - justifyContent(YGJustifyFlexStart), - alignContent(YGAlignFlexStart), - alignItems(YGAlignStretch), - alignSelf(YGAlignAuto), - positionType(YGPositionTypeRelative), - flexWrap(YGWrapNoWrap), - overflow(YGOverflowVisible), - display(YGDisplayFlex) {} + YGStyle() = default; bool operator==(const YGStyle& style); bool operator!=(YGStyle style) { diff --git a/yoga/YGValue.cpp b/yoga/YGValue.cpp deleted file mode 100644 index fcdd0c69..00000000 --- a/yoga/YGValue.cpp +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. - */ -#include "YGValue.h" - -const YGValue YGValueZero = {0, YGUnitPoint}; -const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; -const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; diff --git a/yoga/YGValue.h b/yoga/YGValue.h deleted file mode 100644 index 4e43f7b2..00000000 --- a/yoga/YGValue.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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 "YGEnums.h" -#include "YGMacros.h" - -YG_EXTERN_C_BEGIN - -// Not defined in MSVC++ -#ifndef NAN -static const uint32_t __nan = 0x7fc00000; -#define NAN (*(const float*)__nan) -#endif - -#define YGUndefined NAN - -typedef struct YGValue { - float value; - YGUnit unit; -} YGValue; - -extern const YGValue YGValueAuto; -extern const YGValue YGValueUndefined; -extern const YGValue YGValueZero; - -YG_EXTERN_C_END - -#ifdef __cplusplus - -inline bool operator==(const YGValue& lhs, const YGValue& rhs) { - if (lhs.unit != rhs.unit) { - return false; - } - - switch (lhs.unit) { - case YGUnitUndefined: - case YGUnitAuto: - return true; - case YGUnitPoint: - case YGUnitPercent: - default: - return lhs.value == rhs.value; - } -} - -inline bool operator!=(const YGValue& lhs, const YGValue& rhs) { - return !(lhs == rhs); -} - -#endif diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index ef5e5d8c..1e9a1aaf 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -27,7 +27,15 @@ namespace facebook { namespace yoga { inline bool isUndefined(float value) { - return std::isnan(value); + // Value of a float in the case of it being not defined is 10.1E20. Earlier + // it used to be NAN, the benefit of which was that if NAN is involved in any + // mathematical expression the result was NAN. But since we want to have + // `-ffast-math` flag being used by compiler which assumes that the floating + // point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But + // now if YGUndefined is involved in any mathematical operations this + // value(10.1E20) would change. So the following check makes sure that if the + // value is outside a range (-10E8, 10E8) then it is undefined. + return value >= 10E8 || value <= -10E8; } } // namespace yoga diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index f0327f87..6abfb7d3 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -18,7 +18,10 @@ /* define fmaxf if < VC12 */ #if _MSC_VER < 1800 __forceinline const float fmaxf(const float a, const float b) { - return (a > b) ? a : b; + if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { + return (a > b) ? a : b; + } + return YGFloatIsUndefined(a) ? b : a; } #endif #endif @@ -39,6 +42,23 @@ static int YGDefaultLog( va_list args); #endif +const YGValue YGValueZero = {0, YGUnitPoint}; +const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; +const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; + +bool operator==(const YGValue& lhs, const YGValue& rhs) { + if ((lhs.unit == YGUnitUndefined && rhs.unit == YGUnitUndefined) || + (lhs.unit == YGUnitAuto && rhs.unit == YGUnitAuto)) { + return true; + } + + return lhs.unit == rhs.unit && lhs.value == rhs.value; +} + +bool operator!=(const YGValue& lhs, const YGValue& rhs) { + return !(lhs == rhs); +} + #ifdef ANDROID #include static int YGAndroidLog( @@ -579,18 +599,33 @@ void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode) { } float YGNodeStyleGetFlexGrow(const YGNodeRef node) { - return node->getStyle().flexGrow.orElse(kDefaultFlexGrow); + return node->getStyle().flexGrow.isUndefined() + ? kDefaultFlexGrow + : node->getStyle().flexGrow.getValue(); } float YGNodeStyleGetFlexShrink(const YGNodeRef node) { - return node->getStyle().flexShrink.orElseGet([node] { - return node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink - : kDefaultFlexShrink; - }); + return node->getStyle().flexShrink.isUndefined() + ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink + : kDefaultFlexShrink) + : node->getStyle().flexShrink.getValue(); } namespace { +template +struct StyleProp { + static T get(YGNodeRef node) { + return node->getStyle().*P; + } + static void set(YGNodeRef node, T newValue) { + if (node->getStyle().*P != newValue) { + node->getStyle().*P = newValue; + node->markDirtyAndPropogate(); + } + } +}; + struct Value { template static YGValue create(float value) { @@ -750,88 +785,84 @@ struct DimensionProp { return node->getLayout().instanceName[edge]; \ } -#define YG_NODE_STYLE_SET(node, property, value) \ - if (node->getStyle().property != value) { \ - node->getStyle().property = value; \ - node->markDirtyAndPropogate(); \ - } - -void YGNodeStyleSetDirection(const YGNodeRef node, const YGDirection value) { - YG_NODE_STYLE_SET(node, direction, value); +void YGNodeStyleSetDirection( + const YGNodeRef node, + const YGDirection direction) { + StyleProp::set(node, direction); } YGDirection YGNodeStyleGetDirection(const YGNodeRef node) { - return node->getStyle().direction; + return StyleProp::get(node); } void YGNodeStyleSetFlexDirection( const YGNodeRef node, const YGFlexDirection flexDirection) { - YG_NODE_STYLE_SET(node, flexDirection, flexDirection); + StyleProp::set(node, flexDirection); } YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeRef node) { - return node->getStyle().flexDirection; + return StyleProp::get(node); } void YGNodeStyleSetJustifyContent( const YGNodeRef node, const YGJustify justifyContent) { - YG_NODE_STYLE_SET(node, justifyContent, justifyContent); + StyleProp::set(node, justifyContent); } YGJustify YGNodeStyleGetJustifyContent(const YGNodeRef node) { - return node->getStyle().justifyContent; + return StyleProp::get(node); } void YGNodeStyleSetAlignContent( const YGNodeRef node, const YGAlign alignContent) { - YG_NODE_STYLE_SET(node, alignContent, alignContent); + StyleProp::set(node, alignContent); } YGAlign YGNodeStyleGetAlignContent(const YGNodeRef node) { - return node->getStyle().alignContent; + return StyleProp::get(node); } void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) { - YG_NODE_STYLE_SET(node, alignItems, alignItems); + StyleProp::set(node, alignItems); } YGAlign YGNodeStyleGetAlignItems(const YGNodeRef node) { - return node->getStyle().alignItems; + return StyleProp::get(node); } void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) { - YG_NODE_STYLE_SET(node, alignSelf, alignSelf); + StyleProp::set(node, alignSelf); } YGAlign YGNodeStyleGetAlignSelf(const YGNodeRef node) { - return node->getStyle().alignSelf; + return StyleProp::get(node); } void YGNodeStyleSetPositionType( const YGNodeRef node, const YGPositionType positionType) { - YG_NODE_STYLE_SET(node, positionType, positionType); + StyleProp::set(node, positionType); } YGPositionType YGNodeStyleGetPositionType(const YGNodeRef node) { - return node->getStyle().positionType; + return StyleProp::get(node); } void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) { - YG_NODE_STYLE_SET(node, flexWrap, flexWrap); + StyleProp::set(node, flexWrap); } YGWrap YGNodeStyleGetFlexWrap(const YGNodeRef node) { - return node->getStyle().flexWrap; + return StyleProp::get(node); } void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) { - YG_NODE_STYLE_SET(node, overflow, overflow); + StyleProp::set(node, overflow); } YGOverflow YGNodeStyleGetOverflow(const YGNodeRef node) { - return node->getStyle().overflow; + return StyleProp::get(node); } void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) { - YG_NODE_STYLE_SET(node, display, display); + StyleProp::set(node, display); } YGDisplay YGNodeStyleGetDisplay(const YGNodeRef node) { - return node->getStyle().display; + return StyleProp::get(node); } // TODO(T26792433): Change the API to accept YGFloatOptional. @@ -845,7 +876,8 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { // TODO(T26792433): Change the API to accept YGFloatOptional. float YGNodeStyleGetFlex(const YGNodeRef node) { - return node->getStyle().flex.orElse(YGUndefined); + return node->getStyle().flex.isUndefined() ? YGUndefined + : node->getStyle().flex.getValue(); } // TODO(T26792433): Change the API to accept YGFloatOptional. @@ -947,7 +979,7 @@ float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) { // TODO(T26792433): Change the API to accept YGFloatOptional. float YGNodeStyleGetAspectRatio(const YGNodeRef node) { const YGFloatOptional op = node->getStyle().aspectRatio; - return op.orElse(YGUndefined); + return op.isUndefined() ? YGUndefined : op.getValue(); } // TODO(T26792433): Change the API to accept YGFloatOptional. @@ -1057,7 +1089,7 @@ static void YGNodePrintInternal( const YGNodeRef node, const YGPrintOptions options) { std::string str; - facebook::yoga::YGNodeToString(str, node, options, 0); + facebook::yoga::YGNodeToString(&str, node, options, 0); YGLog(node, YGLogLevelDebug, str.c_str()); } @@ -1084,9 +1116,9 @@ static inline float YGNodePaddingAndBorderForAxis( const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return (node->getLeadingPaddingAndBorder(axis, widthSize) + - node->getTrailingPaddingAndBorder(axis, widthSize)) - .unwrap(); + return YGUnwrapFloatOptional( + node->getLeadingPaddingAndBorder(axis, widthSize) + + node->getTrailingPaddingAndBorder(axis, widthSize)); } static inline YGAlign YGNodeAlignItem( @@ -1168,9 +1200,9 @@ static inline float YGNodeDimWithMargin( const YGFlexDirection axis, const float widthSize) { return node->getLayout().measuredDimensions[dim[axis]] + - (node->getLeadingMargin(axis, widthSize) + - node->getTrailingMargin(axis, widthSize)) - .unwrap(); + YGUnwrapFloatOptional( + node->getLeadingMargin(axis, widthSize) + + node->getTrailingMargin(axis, widthSize)); } static inline bool YGNodeIsStyleDimDefined( @@ -1200,7 +1232,7 @@ static inline bool YGNodeIsLayoutDimDefined( static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( const YGNodeRef node, const YGFlexDirection axis, - const YGFloatOptional value, + const float value, const float axisSize) { YGFloatOptional min; YGFloatOptional max; @@ -1217,15 +1249,15 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( node->getStyle().maxDimensions[YGDimensionWidth], axisSize); } - if (max >= YGFloatOptional{0} && value > max) { + if (!max.isUndefined() && max.getValue() >= 0 && value > max.getValue()) { return max; } - if (min >= YGFloatOptional{0} && value < min) { + if (!min.isUndefined() && min.getValue() >= 0 && value < min.getValue()) { return min; } - return value; + return YGFloatOptional(value); } // Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't @@ -1237,9 +1269,8 @@ static inline float YGNodeBoundAxis( const float axisSize, const float widthSize) { return YGFloatMax( - (YGNodeBoundAxisWithinMinAndMax( - node, axis, YGFloatOptional{value}, axisSize)) - .unwrap(), + YGUnwrapFloatOptional( + YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize)), YGNodePaddingAndBorderForAxis(node, axis, widthSize)); } @@ -1267,14 +1298,14 @@ static void YGConstrainMaxSizeForMode( switch (*mode) { case YGMeasureModeExactly: case YGMeasureModeAtMost: - if (YGFloatOptional{*size} > maxSize) { - *size = maxSize.unwrap(); - } + *size = (maxSize.isUndefined() || *size < maxSize.getValue()) + ? *size + : maxSize.getValue(); break; case YGMeasureModeUndefined: if (!maxSize.isUndefined()) { *mode = YGMeasureModeAtMost; - *size = maxSize.unwrap(); + *size = maxSize.getValue(); } break; } @@ -1315,14 +1346,14 @@ static void YGNodeComputeFlexBasisForChild( child->getConfig(), YGExperimentalFeatureWebFlexBasis) && child->getLayout().computedFlexBasisGeneration != gCurrentGenerationCount)) { - const YGFloatOptional paddingAndBorder = YGFloatOptional( + const YGFloatOptional& paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); child->setLayoutComputedFlexBasis( YGFloatOptionalMax(resolvedFlexBasis, paddingAndBorder)); } } else if (isMainAxisRow && isRowStyleDimDefined) { // The width is definite, so use that as the flex basis. - const YGFloatOptional paddingAndBorder = YGFloatOptional( + const YGFloatOptional& paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( @@ -1331,7 +1362,7 @@ static void YGNodeComputeFlexBasisForChild( paddingAndBorder)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { // The height is definite, so use that as the flex basis. - const YGFloatOptional paddingAndBorder = + const YGFloatOptional& paddingAndBorder = YGFloatOptional(YGNodePaddingAndBorderForAxis( child, YGFlexDirectionColumn, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( @@ -1346,24 +1377,22 @@ static void YGNodeComputeFlexBasisForChild( childWidthMeasureMode = YGMeasureModeUndefined; childHeightMeasureMode = YGMeasureModeUndefined; - auto marginRow = - (child->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); - auto marginColumn = - (child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); + auto marginRow = YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + auto marginColumn = YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); if (isRowStyleDimDefined) { childWidth = - (YGResolveValue( - child->getResolvedDimension(YGDimensionWidth), ownerWidth)) - .unwrap() + + YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionWidth), ownerWidth)) + marginRow; childWidthMeasureMode = YGMeasureModeExactly; } if (isColumnStyleDimDefined) { childHeight = - (YGResolveValue( - child->getResolvedDimension(YGDimensionHeight), ownerHeight)) - .unwrap() + + YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionHeight), ownerHeight)) + marginColumn; childHeightMeasureMode = YGMeasureModeExactly; } @@ -1386,15 +1415,16 @@ static void YGNodeComputeFlexBasisForChild( } } - auto hasAspectRatio = !child->getStyle().aspectRatio.isUndefined(); - auto aspectRatio = child->getStyle().aspectRatio.unwrap(); - if (hasAspectRatio) { + if (!child->getStyle().aspectRatio.isUndefined()) { if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { - childHeight = marginColumn + (childWidth - marginRow) / aspectRatio; + childHeight = marginColumn + + (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); childHeightMeasureMode = YGMeasureModeExactly; } else if ( isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { - childWidth = marginRow + (childHeight - marginColumn) * aspectRatio; + childWidth = marginRow + + (childHeight - marginColumn) * + child->getStyle().aspectRatio.getValue(); childWidthMeasureMode = YGMeasureModeExactly; } } @@ -1412,8 +1442,9 @@ static void YGNodeComputeFlexBasisForChild( childWidthStretch) { childWidth = width; childWidthMeasureMode = YGMeasureModeExactly; - if (hasAspectRatio) { - childHeight = (childWidth - marginRow) / aspectRatio; + if (!child->getStyle().aspectRatio.isUndefined()) { + childHeight = + (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); childHeightMeasureMode = YGMeasureModeExactly; } } @@ -1428,8 +1459,9 @@ static void YGNodeComputeFlexBasisForChild( childHeight = height; childHeightMeasureMode = YGMeasureModeExactly; - if (hasAspectRatio) { - childWidth = (childHeight - marginColumn) * aspectRatio; + if (!child->getStyle().aspectRatio.isUndefined()) { + childWidth = (childHeight - marginColumn) * + child->getStyle().aspectRatio.getValue(); childWidthMeasureMode = YGMeasureModeExactly; } } @@ -1489,14 +1521,13 @@ static void YGNodeAbsoluteLayoutChild( YGMeasureMode childHeightMeasureMode = YGMeasureModeUndefined; auto marginRow = - (child->getMarginForAxis(YGFlexDirectionRow, width)).unwrap(); - auto marginColumn = - (child->getMarginForAxis(YGFlexDirectionColumn, width)).unwrap(); + YGUnwrapFloatOptional(child->getMarginForAxis(YGFlexDirectionRow, width)); + auto marginColumn = YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionColumn, width)); if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { - childWidth = - (YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width)) - .unwrap() + + childWidth = YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionWidth), width)) + marginRow; } else { // If the child doesn't have a specified width, compute the width based @@ -1507,18 +1538,17 @@ static void YGNodeAbsoluteLayoutChild( childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - (node->getLeadingBorder(YGFlexDirectionRow) + node->getTrailingBorder(YGFlexDirectionRow)) - - (child->getLeadingPosition(YGFlexDirectionRow, width) + - child->getTrailingPosition(YGFlexDirectionRow, width)) - .unwrap(); + YGUnwrapFloatOptional( + child->getLeadingPosition(YGFlexDirectionRow, width) + + child->getTrailingPosition(YGFlexDirectionRow, width)); childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); } } if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { - childHeight = - (YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height)) - .unwrap() + + childHeight = YGUnwrapFloatOptional(YGResolveValue( + child->getResolvedDimension(YGDimensionHeight), height)) + marginColumn; } else { // If the child doesn't have a specified height, compute the height @@ -1526,12 +1556,13 @@ static void YGNodeAbsoluteLayoutChild( // offsets if they're defined. if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && child->isTrailingPosDefined(YGFlexDirectionColumn)) { - childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - + childHeight = + node->getLayout().measuredDimensions[YGDimensionHeight] - (node->getLeadingBorder(YGFlexDirectionColumn) + node->getTrailingBorder(YGFlexDirectionColumn)) - - (child->getLeadingPosition(YGFlexDirectionColumn, height) + - child->getTrailingPosition(YGFlexDirectionColumn, height)) - .unwrap(); + YGUnwrapFloatOptional( + child->getLeadingPosition(YGFlexDirectionColumn, height) + + child->getTrailingPosition(YGFlexDirectionColumn, height)); childHeight = YGNodeBoundAxis( child, YGFlexDirectionColumn, childHeight, height, width); } @@ -1542,11 +1573,13 @@ static void YGNodeAbsoluteLayoutChild( // flexible. if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) { if (!child->getStyle().aspectRatio.isUndefined()) { - auto aspectRatio = child->getStyle().aspectRatio.unwrap(); if (YGFloatIsUndefined(childWidth)) { - childWidth = marginRow + (childHeight - marginColumn) * aspectRatio; + childWidth = marginRow + + (childHeight - marginColumn) * + child->getStyle().aspectRatio.getValue(); } else if (YGFloatIsUndefined(childHeight)) { - childHeight = marginColumn + (childWidth - marginRow) / aspectRatio; + childHeight = marginColumn + + (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); } } } @@ -1584,9 +1617,11 @@ static void YGNodeAbsoluteLayoutChild( "abs-measure", config); childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + - (child->getMarginForAxis(YGFlexDirectionRow, width)).unwrap(); + YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionRow, width)); childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] + - (child->getMarginForAxis(YGFlexDirectionColumn, width)).unwrap(); + YGUnwrapFloatOptional( + child->getMarginForAxis(YGFlexDirectionColumn, width)); } YGLayoutNodeInternal( @@ -1608,10 +1643,9 @@ static void YGNodeAbsoluteLayoutChild( node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]] - node->getTrailingBorder(mainAxis) - - (child->getTrailingMargin(mainAxis, width)).unwrap() - - (child->getTrailingPosition( - mainAxis, isMainAxisRow ? width : height)) - .unwrap(), + YGUnwrapFloatOptional(child->getTrailingMargin(mainAxis, width)) - + YGUnwrapFloatOptional(child->getTrailingPosition( + mainAxis, isMainAxisRow ? width : height)), leading[mainAxis]); } else if ( !child->isLeadingPositionDefined(mainAxis) && @@ -1636,10 +1670,9 @@ static void YGNodeAbsoluteLayoutChild( node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]] - node->getTrailingBorder(crossAxis) - - (child->getTrailingMargin(crossAxis, width)).unwrap() - - (child->getTrailingPosition( - crossAxis, isMainAxisRow ? height : width)) - .unwrap(), + YGUnwrapFloatOptional(child->getTrailingMargin(crossAxis, width)) - + YGUnwrapFloatOptional(child->getTrailingPosition( + crossAxis, isMainAxisRow ? height : width)), leading[crossAxis]); } else if ( @@ -1678,10 +1711,10 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis( node, YGFlexDirectionColumn, availableWidth); - const float marginAxisRow = - (node->getMarginForAxis(YGFlexDirectionRow, availableWidth)).unwrap(); - const float marginAxisColumn = - (node->getMarginForAxis(YGFlexDirectionColumn, availableWidth)).unwrap(); + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, availableWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, availableWidth)); // We want to make sure we don't call measure with negative size const float innerWidth = YGFloatIsUndefined(availableWidth) @@ -1756,10 +1789,10 @@ static void YGNodeEmptyContainerSetMeasuredDimensions( YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); - const float marginAxisRow = - (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); - const float marginAxisColumn = - (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); node->setLayoutMeasuredDimension( YGNodeBoundAxis( @@ -1800,10 +1833,10 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) || (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly)) { - auto marginAxisColumn = - (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); - auto marginAxisRow = - (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); + auto marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + auto marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); node->setLayoutMeasuredDimension( YGNodeBoundAxis( @@ -1859,7 +1892,8 @@ static float YGNodeCalculateAvailableInnerDim( YGDimension dimension = YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight; - const float margin = (node->getMarginForAxis(direction, ownerDim)).unwrap(); + const float margin = + YGUnwrapFloatOptional(node->getMarginForAxis(direction, ownerDim)); const float paddingAndBorder = YGNodePaddingAndBorderForAxis(node, direction, ownerDim); @@ -1871,15 +1905,16 @@ static float YGNodeCalculateAvailableInnerDim( // constraints const YGFloatOptional minDimensionOptional = YGResolveValue(node->getStyle().minDimensions[dimension], ownerDim); - const float minInnerDim = - (minDimensionOptional - YGFloatOptional{paddingAndBorder}).orElse(0.0f); + const float minInnerDim = minDimensionOptional.isUndefined() + ? 0.0f + : minDimensionOptional.getValue() - paddingAndBorder; const YGFloatOptional maxDimensionOptional = YGResolveValue(node->getStyle().maxDimensions[dimension], ownerDim); - const float maxInnerDim = - (maxDimensionOptional - YGFloatOptional{paddingAndBorder}) - .orElse(FLT_MAX); + const float maxInnerDim = maxDimensionOptional.isUndefined() + ? FLT_MAX + : maxDimensionOptional.getValue() - paddingAndBorder; availableInnerDim = YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim); } @@ -1963,10 +1998,9 @@ static float YGNodeComputeFlexBasisForChildren( config); } - totalOuterFlexBasis += - (child->getLayout().computedFlexBasis + - child->getMarginForAxis(mainAxis, availableInnerWidth)) - .unwrap(); + totalOuterFlexBasis += YGUnwrapFloatOptional( + child->getLayout().computedFlexBasis + + child->getMarginForAxis(mainAxis, availableInnerWidth)); } return totalOuterFlexBasis; @@ -2001,15 +2035,14 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( continue; } child->setLineIndex(lineCount); - const float childMarginMainAxis = - (child->getMarginForAxis(mainAxis, availableInnerWidth)).unwrap(); + const float childMarginMainAxis = YGUnwrapFloatOptional( + child->getMarginForAxis(mainAxis, availableInnerWidth)); const float flexBasisWithMinAndMaxConstraints = - (YGNodeBoundAxisWithinMinAndMax( - child, - mainAxis, - child->getLayout().computedFlexBasis, - mainAxisownerSize)) - .unwrap(); + YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + child, + mainAxis, + YGUnwrapFloatOptional(child->getLayout().computedFlexBasis), + mainAxisownerSize)); // If this is a multi-line flow and this item pushes us over the // available size, we've @@ -2035,7 +2068,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( // child dimension. flexAlgoRowMeasurement.totalFlexShrinkScaledFactors += -child->resolveFlexShrink() * - (child->getLayout().computedFlexBasis).unwrap(); + YGUnwrapFloatOptional(child->getLayout().computedFlexBasis); } flexAlgoRowMeasurement.relativeChildren.push_back(child); @@ -2082,12 +2115,12 @@ static float YGDistributeFreeSpaceSecondPass( const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - childFlexBasis = (YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - currentRelativeChild->getLayout().computedFlexBasis, - mainAxisownerSize)) - .unwrap(); + childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + YGUnwrapFloatOptional( + currentRelativeChild->getLayout().computedFlexBasis), + mainAxisownerSize)); float updatedMainSize = childFlexBasis; if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && @@ -2137,12 +2170,10 @@ static float YGDistributeFreeSpaceSecondPass( deltaFreeSpace += updatedMainSize - childFlexBasis; - const float marginMain = - (currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth)) - .unwrap(); - const float marginCross = - (currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth)) - .unwrap(); + const float marginMain = YGUnwrapFloatOptional( + currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth)); + const float marginCross = YGUnwrapFloatOptional( + currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth)); float childCrossSize; float childMainSize = updatedMainSize + marginMain; @@ -2151,9 +2182,9 @@ static float YGDistributeFreeSpaceSecondPass( if (!currentRelativeChild->getStyle().aspectRatio.isUndefined()) { childCrossSize = isMainAxisRow ? (childMainSize - marginMain) / - currentRelativeChild->getStyle().aspectRatio.unwrap() + currentRelativeChild->getStyle().aspectRatio.getValue() : (childMainSize - marginMain) * - currentRelativeChild->getStyle().aspectRatio.unwrap(); + currentRelativeChild->getStyle().aspectRatio.getValue(); childCrossMeasureMode = YGMeasureModeExactly; childCrossSize += marginCross; @@ -2178,10 +2209,9 @@ static float YGDistributeFreeSpaceSecondPass( : YGMeasureModeAtMost; } else { childCrossSize = - (YGResolveValue( - currentRelativeChild->getResolvedDimension(dim[crossAxis]), - availableInnerCrossDim)) - .unwrap() + + YGUnwrapFloatOptional(YGResolveValue( + currentRelativeChild->getResolvedDimension(dim[crossAxis]), + availableInnerCrossDim)) + marginCross; const bool isLoosePercentageMeasurement = currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit == @@ -2261,13 +2291,12 @@ static void YGDistributeFreeSpaceFirstPass( float deltaFreeSpace = 0; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - float childFlexBasis = - (YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - currentRelativeChild->getLayout().computedFlexBasis, - mainAxisownerSize)) - .unwrap(); + float childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + YGUnwrapFloatOptional( + currentRelativeChild->getLayout().computedFlexBasis), + mainAxisownerSize)); if (collectedFlexItemsValues.remainingFreeSpace < 0) { flexShrinkScaledFactor = @@ -2418,10 +2447,10 @@ static void YGJustifyMainAxis( const float availableInnerWidth, const bool performLayout) { const YGStyle& style = node->getStyle(); - const float leadingPaddingAndBorderMain = - (node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)).unwrap(); - const float trailingPaddingAndBorderMain = - (node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)).unwrap(); + const float leadingPaddingAndBorderMain = YGUnwrapFloatOptional( + node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)); + const float trailingPaddingAndBorderMain = YGUnwrapFloatOptional( + node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)); // If we are using "at most" rules in the main axis, make sure that // remainingFreeSpace is 0 when min main dimension is not given if (measureModeMainDim == YGMeasureModeAtMost && @@ -2437,9 +2466,8 @@ static void YGJustifyMainAxis( // `minAvailableMainDim` denotes minimum available space in which child // can be laid out, it will exclude space consumed by padding and border. const float minAvailableMainDim = - (YGResolveValue( - style.minDimensions[dim[mainAxis]], mainAxisownerSize)) - .unwrap() - + YGUnwrapFloatOptional(YGResolveValue( + style.minDimensions[dim[mainAxis]], mainAxisownerSize)) - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; const float occupiedSpaceByChildNodes = availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace; @@ -2529,11 +2557,11 @@ static void YGJustifyMainAxis( // defined, we override the position to whatever the user said // (and margin/border). child->setLayoutPosition( - (child->getLeadingPosition(mainAxis, availableInnerMainDim)) - .unwrap() + + YGUnwrapFloatOptional( + child->getLeadingPosition(mainAxis, availableInnerMainDim)) + node->getLeadingBorder(mainAxis) + - (child->getLeadingMargin(mainAxis, availableInnerWidth)) - .unwrap(), + YGUnwrapFloatOptional( + child->getLeadingMargin(mainAxis, availableInnerWidth)), pos[mainAxis]); } } else { @@ -2567,9 +2595,9 @@ static void YGJustifyMainAxis( // they weren't computed. This means we can't call // YGNodeDimWithMargin. collectedFlexItemsValues.mainDim += betweenMainDim + - (child->getMarginForAxis(mainAxis, availableInnerWidth)) - .unwrap() + - (childLayout.computedFlexBasis).unwrap(); + YGUnwrapFloatOptional(child->getMarginForAxis( + mainAxis, availableInnerWidth)) + + YGUnwrapFloatOptional(childLayout.computedFlexBasis); collectedFlexItemsValues.crossDim = availableInnerCrossDim; } else { // The main dimension is the sum of all the elements dimension plus @@ -2581,14 +2609,12 @@ static void YGJustifyMainAxis( // If the child is baseline aligned then the cross dimension is // calculated by adding maxAscent and maxDescent from the baseline. const float ascent = YGBaseline(child) + - (child->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth)) - .unwrap(); + YGUnwrapFloatOptional(child->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth)); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + - (child->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth)) - .unwrap() - + YGUnwrapFloatOptional(child->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth)) - ascent; maxAscentForCurrentLine = @@ -2741,16 +2767,20 @@ static void YGNodelayoutImpl( YGResolveFlexDirection(YGFlexDirectionColumn, direction); node->setLayoutMargin( - (node->getLeadingMargin(flexRowDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getLeadingMargin(flexRowDirection, ownerWidth)), YGEdgeStart); node->setLayoutMargin( - (node->getTrailingMargin(flexRowDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getTrailingMargin(flexRowDirection, ownerWidth)), YGEdgeEnd); node->setLayoutMargin( - (node->getLeadingMargin(flexColumnDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getLeadingMargin(flexColumnDirection, ownerWidth)), YGEdgeTop); node->setLayoutMargin( - (node->getTrailingMargin(flexColumnDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getTrailingMargin(flexColumnDirection, ownerWidth)), YGEdgeBottom); node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), YGEdgeStart); @@ -2760,16 +2790,20 @@ static void YGNodelayoutImpl( node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); node->setLayoutPadding( - (node->getLeadingPadding(flexRowDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getLeadingPadding(flexRowDirection, ownerWidth)), YGEdgeStart); node->setLayoutPadding( - (node->getTrailingPadding(flexRowDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getTrailingPadding(flexRowDirection, ownerWidth)), YGEdgeEnd); node->setLayoutPadding( - (node->getLeadingPadding(flexColumnDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getLeadingPadding(flexColumnDirection, ownerWidth)), YGEdgeTop); node->setLayoutPadding( - (node->getTrailingPadding(flexColumnDirection, ownerWidth)).unwrap(), + YGUnwrapFloatOptional( + node->getTrailingPadding(flexColumnDirection, ownerWidth)), YGEdgeBottom); if (node->getMeasure() != nullptr) { @@ -2827,8 +2861,8 @@ static void YGNodelayoutImpl( const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth; - const float leadingPaddingAndBorderCross = - (node->getLeadingPaddingAndBorder(crossAxis, ownerWidth)).unwrap(); + const float leadingPaddingAndBorderCross = YGUnwrapFloatOptional( + node->getLeadingPaddingAndBorder(crossAxis, ownerWidth)); const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); const float paddingAndBorderAxisCross = @@ -2844,30 +2878,26 @@ static void YGNodelayoutImpl( const float paddingAndBorderAxisColumn = isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; - const float marginAxisRow = - (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); - const float marginAxisColumn = - (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); const float minInnerWidth = - (YGResolveValue( - node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) - .unwrap() - + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) - paddingAndBorderAxisRow; const float maxInnerWidth = - (YGResolveValue( - node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - .unwrap() - + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - paddingAndBorderAxisRow; const float minInnerHeight = - (YGResolveValue( - node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) - .unwrap() - + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) - paddingAndBorderAxisColumn; const float maxInnerHeight = - (YGResolveValue( - node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) - .unwrap() - + YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) - paddingAndBorderAxisColumn; const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; @@ -3078,11 +3108,11 @@ static void YGNodelayoutImpl( child->isLeadingPositionDefined(crossAxis); if (isChildLeadingPosDefined) { child->setLayoutPosition( - (child->getLeadingPosition(crossAxis, availableInnerCrossDim)) - .unwrap() + + YGUnwrapFloatOptional(child->getLeadingPosition( + crossAxis, availableInnerCrossDim)) + node->getLeadingBorder(crossAxis) + - (child->getLeadingMargin(crossAxis, availableInnerWidth)) - .unwrap(), + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), pos[crossAxis]); } // If leading position is not defined or calculations result in Nan, @@ -3091,8 +3121,8 @@ static void YGNodelayoutImpl( YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) { child->setLayoutPosition( node->getLeadingBorder(crossAxis) + - (child->getLeadingMargin(crossAxis, availableInnerWidth)) - .unwrap(), + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), pos[crossAxis]); } } else { @@ -3118,17 +3148,16 @@ static void YGNodelayoutImpl( child->getLayout().measuredDimensions[dim[mainAxis]]; float childCrossSize = !child->getStyle().aspectRatio.isUndefined() - ? (((child->getMarginForAxis(crossAxis, availableInnerWidth)) - .unwrap() + + ? ((YGUnwrapFloatOptional(child->getMarginForAxis( + crossAxis, availableInnerWidth)) + (isMainAxisRow ? childMainSize / - child->getStyle().aspectRatio.unwrap() + child->getStyle().aspectRatio.getValue() : childMainSize * - child->getStyle().aspectRatio.unwrap()))) + child->getStyle().aspectRatio.getValue()))) : collectedFlexItemsValues.crossDim; - childMainSize += - (child->getMarginForAxis(mainAxis, availableInnerWidth)) - .unwrap(); + childMainSize += YGUnwrapFloatOptional( + child->getMarginForAxis(mainAxis, availableInnerWidth)); YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly; @@ -3270,19 +3299,17 @@ static void YGNodelayoutImpl( lineHeight = YGFloatMax( lineHeight, child->getLayout().measuredDimensions[dim[crossAxis]] + - (child->getMarginForAxis(crossAxis, availableInnerWidth)) - .unwrap()); + YGUnwrapFloatOptional(child->getMarginForAxis( + crossAxis, availableInnerWidth))); } if (YGNodeAlignItem(node, child) == YGAlignBaseline) { const float ascent = YGBaseline(child) + - (child->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth)) - .unwrap(); + YGUnwrapFloatOptional(child->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth)); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + - (child->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth)) - .unwrap() - + YGUnwrapFloatOptional(child->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth)) - ascent; maxAscentForCurrentLine = YGFloatMax(maxAscentForCurrentLine, ascent); @@ -3307,18 +3334,16 @@ static void YGNodelayoutImpl( case YGAlignFlexStart: { child->setLayoutPosition( currentLead + - (child->getLeadingMargin( - crossAxis, availableInnerWidth)) - .unwrap(), + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), pos[crossAxis]); break; } case YGAlignFlexEnd: { child->setLayoutPosition( currentLead + lineHeight - - (child->getTrailingMargin( - crossAxis, availableInnerWidth)) - .unwrap() - + YGUnwrapFloatOptional(child->getTrailingMargin( + crossAxis, availableInnerWidth)) - child->getLayout().measuredDimensions[dim[crossAxis]], pos[crossAxis]); break; @@ -3335,9 +3360,8 @@ static void YGNodelayoutImpl( case YGAlignStretch: { child->setLayoutPosition( currentLead + - (child->getLeadingMargin( - crossAxis, availableInnerWidth)) - .unwrap(), + YGUnwrapFloatOptional(child->getLeadingMargin( + crossAxis, availableInnerWidth)), pos[crossAxis]); // Remeasure child with the line height as it as been only @@ -3347,17 +3371,15 @@ static void YGNodelayoutImpl( const float childWidth = isMainAxisRow ? (child->getLayout() .measuredDimensions[YGDimensionWidth] + - (child->getMarginForAxis( - mainAxis, availableInnerWidth)) - .unwrap()) + YGUnwrapFloatOptional(child->getMarginForAxis( + mainAxis, availableInnerWidth))) : lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout() .measuredDimensions[YGDimensionHeight] + - (child->getMarginForAxis( - crossAxis, availableInnerWidth)) - .unwrap()) + YGUnwrapFloatOptional(child->getMarginForAxis( + crossAxis, availableInnerWidth))) : lineHeight; if (!(YGFloatsEqual( @@ -3387,9 +3409,8 @@ static void YGNodelayoutImpl( case YGAlignBaseline: { child->setLayoutPosition( currentLead + maxAscentForCurrentLine - YGBaseline(child) + - (child->getLeadingPosition( - YGFlexDirectionColumn, availableInnerCrossDim)) - .unwrap(), + YGUnwrapFloatOptional(child->getLeadingPosition( + YGFlexDirectionColumn, availableInnerCrossDim)), YGEdgeTop); break; @@ -3445,12 +3466,8 @@ static void YGNodelayoutImpl( YGFloatMax( YGFloatMin( availableInnerMainDim + paddingAndBorderAxisMain, - (YGNodeBoundAxisWithinMinAndMax( - node, - mainAxis, - YGFloatOptional{maxLineMainDim}, - mainAxisownerSize)) - .unwrap()), + YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + node, mainAxis, maxLineMainDim, mainAxisownerSize))), paddingAndBorderAxisMain), dim[mainAxis]); } @@ -3476,13 +3493,11 @@ static void YGNodelayoutImpl( YGFloatMax( YGFloatMin( availableInnerCrossDim + paddingAndBorderAxisCross, - (YGNodeBoundAxisWithinMinAndMax( - node, - crossAxis, - YGFloatOptional{totalLineCrossDim + - paddingAndBorderAxisCross}, - crossAxisownerSize)) - .unwrap()), + YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + node, + crossAxis, + totalLineCrossDim + paddingAndBorderAxisCross, + crossAxisownerSize))), paddingAndBorderAxisCross), dim[crossAxis]); } @@ -3782,10 +3797,10 @@ bool YGLayoutNodeInternal( // expensive to measure, so it's worth avoiding redundant measurements if at // all possible. if (node->getMeasure() != nullptr) { - const float marginAxisRow = - (node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)).unwrap(); - const float marginAxisColumn = - (node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)).unwrap(); + const float marginAxisRow = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + const float marginAxisColumn = YGUnwrapFloatOptional( + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); // First, try to use the layout cache. if (YGNodeCanUseCachedMeasurement( @@ -4085,18 +4100,16 @@ void YGNodeCalculateLayout( float width = YGUndefined; YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { - width = - (YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) - .unwrap(); + width = YGUnwrapFloatOptional( + YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); widthMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue( node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth) .isUndefined()) { - width = (YGResolveValue( - node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - .unwrap(); + width = YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)); widthMeasureMode = YGMeasureModeAtMost; } else { width = ownerWidth; @@ -4107,20 +4120,18 @@ void YGNodeCalculateLayout( float height = YGUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { - height = (YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionColumn]), - ownerHeight) + - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) - .unwrap(); + height = YGUnwrapFloatOptional( + YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionColumn]), + ownerHeight) + + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); heightMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue( node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight) .isUndefined()) { - height = - (YGResolveValue( - node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) - .unwrap(); + height = YGUnwrapFloatOptional(YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)); heightMeasureMode = YGMeasureModeAtMost; } else { height = ownerHeight; diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 787af6df..96e71dc7 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -17,9 +17,17 @@ #include #endif +/** Large positive number signifies that the property(float) is undefined. + *Earlier we used to have YGundefined as NAN, but the downside of this is that + *we can't use -ffast-math compiler flag as it assumes all floating-point + *calculation involve and result into finite numbers. For more information + *regarding -ffast-math compiler flag in clang, have a look at + *https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math + **/ +#define YGUndefined 10E20F + #include "YGEnums.h" #include "YGMacros.h" -#include "YGValue.h" YG_EXTERN_C_BEGIN @@ -28,6 +36,25 @@ typedef struct YGSize { float height; } YGSize; +typedef struct YGValue { + float value; + YGUnit unit; +} YGValue; + +extern const YGValue YGValueUndefined; +extern const YGValue YGValueAuto; + +#ifdef __cplusplus + +YG_EXTERN_C_END + +extern bool operator==(const YGValue& lhs, const YGValue& rhs); +extern bool operator!=(const YGValue& lhs, const YGValue& rhs); + +YG_EXTERN_C_BEGIN + +#endif + typedef struct YGConfig* YGConfigRef; typedef struct YGNode* YGNodeRef; -- 2.50.1.windows.1 From e522b2dee4630e79b11b3209e11dd9fba85fcb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Sj=C3=B6lander?= Date: Mon, 10 Dec 2018 09:20:32 -0800 Subject: [PATCH 24/53] Fix aspect ratio when stretching with main axis margin (#834) Summary: I've noticed that when a child's size is determined by `align-items: stretch` in combination with `aspect-ratio` its size is wrongly calculated to account for margin in the main axis when there is more than enough space. See playground: https://goo.gl/tgW6cD I've yet to figure out exactly how to solve this but i've started by writing a failing test when can be seen in the first commit here. I assumed I had found the bug here https://github.com/facebook/yoga/blob/master/yoga/Yoga.cpp#L1838 where margin is being subtracted from the desired width even though the measure mode tells it to measure to exactly that size. However, if we don't remove this margin from the available width then 15 tests fail (including the one I just added) not quite figured out why yet. I'm also a bit confused at to why this would only happen for nodes with `aspect-ratio` and not for nodes where an explicit height and width is set. Pull Request resolved: https://github.com/facebook/yoga/pull/834 Reviewed By: astreet Differential Revision: D13223579 Pulled By: davidaurelio fbshipit-source-id: 6970e6072e79f3bb6f9097355ab6e441441bfd88 --- tests/YGAspectRatioTest.cpp | 23 +++++++++++++++++++++++ yoga/Yoga.cpp | 10 ++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp index 9d99569b..c3e5154f 100644 --- a/tests/YGAspectRatioTest.cpp +++ b/tests/YGAspectRatioTest.cpp @@ -895,3 +895,26 @@ TEST(YogaTest, aspect_ratio_should_prefer_flexed_dimension) { YGNodeFreeRecursive(root); } + +TEST( + YogaTest, + aspect_ratio_defined_by_cross_stretch_should_not_be_effected_by_margin_on_main_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeStart, 50); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); +} diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 6abfb7d3..6bc264a1 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1382,6 +1382,16 @@ static void YGNodeComputeFlexBasisForChild( auto marginColumn = YGUnwrapFloatOptional( child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + if (YGNodeAlignItem(node, child) == YGAlignStretch) { + if (isMainAxisRow && !YGFloatIsUndefined(height)) { + childHeight = height; + childHeightMeasureMode = YGMeasureModeExactly; + } else if (!isMainAxisRow && !YGFloatIsUndefined(width)) { + childWidth = width; + childWidthMeasureMode = YGMeasureModeExactly; + } + } + if (isRowStyleDimDefined) { childWidth = YGUnwrapFloatOptional(YGResolveValue( -- 2.50.1.windows.1 From 440c7191906250cdca864a418926f40dcd0e09b2 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Wed, 12 Dec 2018 05:55:30 -0800 Subject: [PATCH 25/53] added baseline and setIsReferenceBaseline doc in yoga website Summary: Added docs for align-items BASELINE property and yoga node setIsReferenceBaseline property in yoga website Reviewed By: davidaurelio Differential Revision: D13359436 fbshipit-source-id: 34cbb1087c70d44ec6462048cc2a819daf5951e0 --- website/contents/properties/align-items.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/contents/properties/align-items.md b/website/contents/properties/align-items.md index 9fe02d41..955b89f4 100644 --- a/website/contents/properties/align-items.md +++ b/website/contents/properties/align-items.md @@ -18,6 +18,8 @@ applying to the main axis, `align items` applies to the cross axis. **CENTER** Align children of a container in the center of the container's cross axis. +**BASELINE** Align children of a container along a common baseline. Individual children can be set to be the reference baseline for their parents. + ## Align Self -- 2.50.1.windows.1 From 8ab01fde6eccc7babef8ce09fc6fcc395adb7617 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Wed, 12 Dec 2018 16:11:46 -0800 Subject: [PATCH 26/53] Back out "[yoga][PR] Fix aspect ratio when stretching with main axis margin" Summary: Original commit changeset: 6970e6072e79 Reviewed By: mdvacca Differential Revision: D13437552 fbshipit-source-id: 65a55d716da6b6582e38efa906d3f540e58418bf --- tests/YGAspectRatioTest.cpp | 23 ----------------------- yoga/Yoga.cpp | 10 ---------- 2 files changed, 33 deletions(-) diff --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp index c3e5154f..9d99569b 100644 --- a/tests/YGAspectRatioTest.cpp +++ b/tests/YGAspectRatioTest.cpp @@ -895,26 +895,3 @@ TEST(YogaTest, aspect_ratio_should_prefer_flexed_dimension) { YGNodeFreeRecursive(root); } - -TEST( - YogaTest, - aspect_ratio_defined_by_cross_stretch_should_not_be_effected_by_margin_on_main_axis) { - const YGConfigRef config = YGConfigNew(); - YGConfigSetUseWebDefaults(config, true); - - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetWidth(root, 200); - YGNodeStyleSetHeight(root, 100); - - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetMargin(root_child0, YGEdgeStart, 50); - YGNodeStyleSetAspectRatio(root_child0, 1); - YGNodeInsertChild(root, root_child0, 0); - - YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); - - ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); - ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); - - YGNodeFreeRecursive(root); -} diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 6bc264a1..6abfb7d3 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1382,16 +1382,6 @@ static void YGNodeComputeFlexBasisForChild( auto marginColumn = YGUnwrapFloatOptional( child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); - if (YGNodeAlignItem(node, child) == YGAlignStretch) { - if (isMainAxisRow && !YGFloatIsUndefined(height)) { - childHeight = height; - childHeightMeasureMode = YGMeasureModeExactly; - } else if (!isMainAxisRow && !YGFloatIsUndefined(width)) { - childWidth = width; - childWidthMeasureMode = YGMeasureModeExactly; - } - } - if (isRowStyleDimDefined) { childWidth = YGUnwrapFloatOptional(YGResolveValue( -- 2.50.1.windows.1 From 9ddda3c6302d79d8174cfd336a61d84b5705d75b Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:28 -0800 Subject: [PATCH 27/53] Roll back `-ffast-math` Summary: @public `-ffast-math` does not have measurable performance benefits. By using `NaN` for *undefined* values again, we can squeeze `YGFloatOptional` into 32 bits. This will also enable us to store `YGValue` (or a variant of it) in 32 bits. Reviewed By: astreet Differential Revision: D13403925 fbshipit-source-id: b13d026bf556f24ab4699e65fb450af13a70961b --- csharp/Facebook.Yoga/YogaConstants.cs | 23 +++-------------- java/com/facebook/yoga/YogaConstants.java | 30 +++++------------------ tools/build_defs/oss/yoga_defs.bzl | 1 - yoga/Utils.h | 14 +++-------- yoga/Yoga-internal.h | 10 +------- yoga/Yoga.cpp | 5 +--- yoga/Yoga.h | 15 ++++++------ 7 files changed, 21 insertions(+), 77 deletions(-) diff --git a/csharp/Facebook.Yoga/YogaConstants.cs b/csharp/Facebook.Yoga/YogaConstants.cs index a715b43c..9e05cca3 100644 --- a/csharp/Facebook.Yoga/YogaConstants.cs +++ b/csharp/Facebook.Yoga/YogaConstants.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -9,28 +9,11 @@ namespace Facebook.Yoga { public static class YogaConstants { - /** - * Large positive number signifies that the property(float) is undefined. Earlier we used to have - * YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as - * it assumes all floating-point calculation involve and result into finite numbers. For more - * information regarding -ffast-math compiler flag in clang, have a look at - * https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math - */ - public const float Undefined = 10E20F; + public const float Undefined = float.NaN; public static bool IsUndefined(float value) { - // Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN, - // the benefit of which - // was that if NAN is involved in any mathematical expression the result was NAN. But since we - // want to have `-ffast-math` - // flag being used by compiler which assumes that the floating point values are not NAN and Inf, - // we represent YGUndefined as 10.1E20. - // But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would - // change. - // So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it - // is undefined. - return value >= 10E8F || value <= -10E8; + return float.IsNaN(value); } public static bool IsUndefined(YogaValue value) diff --git a/java/com/facebook/yoga/YogaConstants.java b/java/com/facebook/yoga/YogaConstants.java index 61e212ef..b04a7e53 100644 --- a/java/com/facebook/yoga/YogaConstants.java +++ b/java/com/facebook/yoga/YogaConstants.java @@ -1,35 +1,17 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. +/** + * Copyright (c) Facebook, Inc. and its affiliates. * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. */ package com.facebook.yoga; public class YogaConstants { - /** - * Large positive number signifies that the property(float) is undefined. Earlier we used to have - * YGundefined as NAN, but the downside of this is that we can't use -ffast-math compiler flag as - * it assumes all floating-point calculation involve and result into finite numbers. For more - * information regarding -ffast-math compiler flag in clang, have a look at - * https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math - */ - public static final float UNDEFINED = (float) (10E20); + public static final float UNDEFINED = Float.NaN; public static boolean isUndefined(float value) { - // Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN, - // the benefit of which - // was that if NAN is involved in any mathematical expression the result was NAN. But since we - // want to have `-ffast-math` - // flag being used by compiler which assumes that the floating point values are not NAN and Inf, - // we represent YGUndefined as 10.1E20. - // But now if YGUndefined is involved in any mathematical operations this value(10.1E20) would - // change. - // So the following check makes sure that if the value is outside a range (-10E8, 10E8) then it - // is undefined. - return (Float.compare(value, (float) 10E8) >= 0 || Float.compare(value, (float) -10E8) <= 0); + return Float.compare(value, UNDEFINED) == 0; } public static boolean isUndefined(YogaValue value) { diff --git a/tools/build_defs/oss/yoga_defs.bzl b/tools/build_defs/oss/yoga_defs.bzl index 7eca7b9b..5a5872fe 100644 --- a/tools/build_defs/oss/yoga_defs.bzl +++ b/tools/build_defs/oss/yoga_defs.bzl @@ -58,7 +58,6 @@ BASE_COMPILER_FLAGS = [ "-Wall", "-Werror", "-O3", - "-ffast-math", ] LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [ diff --git a/yoga/Utils.h b/yoga/Utils.h index d578511c..d007ff54 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -57,22 +57,12 @@ bool YGValueEqual(const YGValue a, const YGValue b); // difference between two floats is less than 0.0001f or both are undefined. bool YGFloatsEqual(const float a, const float b); -// We need custom max function, since we want that, if one argument is -// YGUndefined then the max funtion should return the other argument as the max -// value. We wouldn't have needed a custom max function if YGUndefined was NAN -// as fmax has the same behaviour, but with NAN we cannot use `-ffast-math` -// compiler flag. float YGFloatMax(const float a, const float b); YGFloatOptional YGFloatOptionalMax( const YGFloatOptional& op1, const YGFloatOptional& op2); -// We need custom min function, since we want that, if one argument is -// YGUndefined then the min funtion should return the other argument as the min -// value. We wouldn't have needed a custom min function if YGUndefined was NAN -// as fmin has the same behaviour, but with NAN we cannot use `-ffast-math` -// compiler flag. float YGFloatMin(const float a, const float b); // This custom float comparision function compares the array of float with @@ -106,7 +96,9 @@ inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { flexDirection == YGFlexDirectionRowReverse; } -inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) { +inline YGFloatOptional YGResolveValue( + const YGValue value, + const float ownerSize) { switch (value.unit) { case YGUnitUndefined: case YGUnitAuto: diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 1e9a1aaf..ef5e5d8c 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -27,15 +27,7 @@ namespace facebook { namespace yoga { inline bool isUndefined(float value) { - // Value of a float in the case of it being not defined is 10.1E20. Earlier - // it used to be NAN, the benefit of which was that if NAN is involved in any - // mathematical expression the result was NAN. But since we want to have - // `-ffast-math` flag being used by compiler which assumes that the floating - // point values are not NAN and Inf, we represent YGUndefined as 10.1E20. But - // now if YGUndefined is involved in any mathematical operations this - // value(10.1E20) would change. So the following check makes sure that if the - // value is outside a range (-10E8, 10E8) then it is undefined. - return value >= 10E8 || value <= -10E8; + return std::isnan(value); } } // namespace yoga diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 6abfb7d3..d5fc12ef 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -18,10 +18,7 @@ /* define fmaxf if < VC12 */ #if _MSC_VER < 1800 __forceinline const float fmaxf(const float a, const float b) { - if (!YGFloatIsUndefined(a) && !YGFloatIsUndefined(b)) { - return (a > b) ? a : b; - } - return YGFloatIsUndefined(a) ? b : a; + return (a > b) ? a : b; } #endif #endif diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 96e71dc7..61aae0fe 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -17,14 +17,13 @@ #include #endif -/** Large positive number signifies that the property(float) is undefined. - *Earlier we used to have YGundefined as NAN, but the downside of this is that - *we can't use -ffast-math compiler flag as it assumes all floating-point - *calculation involve and result into finite numbers. For more information - *regarding -ffast-math compiler flag in clang, have a look at - *https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math - **/ -#define YGUndefined 10E20F +// Not defined in MSVC++ +#ifndef NAN +static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; +#define NAN (*(const float*)__nan) +#endif + +#define YGUndefined NAN #include "YGEnums.h" #include "YGMacros.h" -- 2.50.1.windows.1 From f23a669ed0dcb5b0b9b9922e5f1fdd911b7ee962 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:28 -0800 Subject: [PATCH 28/53] Move out `YGValue` Summary: @public Creates a single header file for `YGValue`. This is in preparation of a more compact representation of `YGValue` within `YGStyle`. Also fixes the incorrect definition of NAN. Reviewed By: SidharthGuglani Differential Revision: D13439602 fbshipit-source-id: 68eef2c391b6c9810f3c995b86fff7204ebe6511 --- yoga/YGValue.cpp | 29 +++++++++++++++++++++++++++++ yoga/YGValue.h | 40 ++++++++++++++++++++++++++++++++++++++++ yoga/Yoga.cpp | 17 ----------------- yoga/Yoga.h | 28 +--------------------------- 4 files changed, 70 insertions(+), 44 deletions(-) create mode 100644 yoga/YGValue.cpp create mode 100644 yoga/YGValue.h diff --git a/yoga/YGValue.cpp b/yoga/YGValue.cpp new file mode 100644 index 00000000..4bfe083d --- /dev/null +++ b/yoga/YGValue.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + */ +#include "YGValue.h" + +const YGValue YGValueZero = {0, YGUnitPoint}; +const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; +const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; + +bool operator==(const YGValue& lhs, const YGValue& rhs) { + if (lhs.unit != rhs.unit) { + return false; + } + + switch (lhs.unit) { + case YGUnitUndefined: + case YGUnitAuto: + return true; + default: + return lhs.value == rhs.value; + } +} + +bool operator!=(const YGValue& lhs, const YGValue& rhs) { + return !(lhs == rhs); +} diff --git a/yoga/YGValue.h b/yoga/YGValue.h new file mode 100644 index 00000000..803b8e78 --- /dev/null +++ b/yoga/YGValue.h @@ -0,0 +1,40 @@ +/** + * Copyright (c) Facebook, Inc. and its 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 "YGEnums.h" +#include "YGMacros.h" + +YG_EXTERN_C_BEGIN + +// Not defined in MSVC++ +#ifndef NAN +static const uint32_t __nan = 0x7fc00000; +#define NAN (*(const float*)__nan) +#endif + +#define YGUndefined NAN + +typedef struct YGValue { + float value; + YGUnit unit; +} YGValue; + +extern const YGValue YGValueAuto; +extern const YGValue YGValueUndefined; +extern const YGValue YGValueZero; + +YG_EXTERN_C_END + +#ifdef __cplusplus + +bool operator==(const YGValue& lhs, const YGValue& rhs); + +bool operator!=(const YGValue& lhs, const YGValue& rhs); + +#endif diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index d5fc12ef..246e0f41 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -39,23 +39,6 @@ static int YGDefaultLog( va_list args); #endif -const YGValue YGValueZero = {0, YGUnitPoint}; -const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; -const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; - -bool operator==(const YGValue& lhs, const YGValue& rhs) { - if ((lhs.unit == YGUnitUndefined && rhs.unit == YGUnitUndefined) || - (lhs.unit == YGUnitAuto && rhs.unit == YGUnitAuto)) { - return true; - } - - return lhs.unit == rhs.unit && lhs.value == rhs.value; -} - -bool operator!=(const YGValue& lhs, const YGValue& rhs) { - return !(lhs == rhs); -} - #ifdef ANDROID #include static int YGAndroidLog( diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 61aae0fe..787af6df 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -17,16 +17,9 @@ #include #endif -// Not defined in MSVC++ -#ifndef NAN -static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; -#define NAN (*(const float*)__nan) -#endif - -#define YGUndefined NAN - #include "YGEnums.h" #include "YGMacros.h" +#include "YGValue.h" YG_EXTERN_C_BEGIN @@ -35,25 +28,6 @@ typedef struct YGSize { float height; } YGSize; -typedef struct YGValue { - float value; - YGUnit unit; -} YGValue; - -extern const YGValue YGValueUndefined; -extern const YGValue YGValueAuto; - -#ifdef __cplusplus - -YG_EXTERN_C_END - -extern bool operator==(const YGValue& lhs, const YGValue& rhs); -extern bool operator!=(const YGValue& lhs, const YGValue& rhs); - -YG_EXTERN_C_BEGIN - -#endif - typedef struct YGConfig* YGConfigRef; typedef struct YGNode* YGNodeRef; -- 2.50.1.windows.1 From e9078374c98a471335a365595b2c3fbc86f19958 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:29 -0800 Subject: [PATCH 29/53] Make equality operator for `YGValue` inlineable Summary: @public Makes `operator==` for `YGValue` an inline function. Reviewed By: SidharthGuglani Differential Revision: D13439601 fbshipit-source-id: c5dd1f35c40f0ffa8224ee2f40ac7cc3cd8e3cf9 --- yoga/YGValue.cpp | 18 ------------------ yoga/YGValue.h | 20 ++++++++++++++++++-- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/yoga/YGValue.cpp b/yoga/YGValue.cpp index 4bfe083d..fcdd0c69 100644 --- a/yoga/YGValue.cpp +++ b/yoga/YGValue.cpp @@ -9,21 +9,3 @@ const YGValue YGValueZero = {0, YGUnitPoint}; const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; - -bool operator==(const YGValue& lhs, const YGValue& rhs) { - if (lhs.unit != rhs.unit) { - return false; - } - - switch (lhs.unit) { - case YGUnitUndefined: - case YGUnitAuto: - return true; - default: - return lhs.value == rhs.value; - } -} - -bool operator!=(const YGValue& lhs, const YGValue& rhs) { - return !(lhs == rhs); -} diff --git a/yoga/YGValue.h b/yoga/YGValue.h index 803b8e78..4e43f7b2 100644 --- a/yoga/YGValue.h +++ b/yoga/YGValue.h @@ -33,8 +33,24 @@ YG_EXTERN_C_END #ifdef __cplusplus -bool operator==(const YGValue& lhs, const YGValue& rhs); +inline bool operator==(const YGValue& lhs, const YGValue& rhs) { + if (lhs.unit != rhs.unit) { + return false; + } -bool operator!=(const YGValue& lhs, const YGValue& rhs); + switch (lhs.unit) { + case YGUnitUndefined: + case YGUnitAuto: + return true; + case YGUnitPoint: + case YGUnitPercent: + default: + return lhs.value == rhs.value; + } +} + +inline bool operator!=(const YGValue& lhs, const YGValue& rhs) { + return !(lhs == rhs); +} #endif -- 2.50.1.windows.1 From da678ef9711d9b437bba15bd58f21393ad2f8b33 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:29 -0800 Subject: [PATCH 30/53] Add tests for `YGFloatOptional` Summary: @public Adds tests for `YGFloatOptional`, to ease refactorings. Reviewed By: SidharthGuglani Differential Revision: D13439610 fbshipit-source-id: e29da7f85ccedc46520b59f6c893bad521d35417 --- tests/YGFloatOptionalTest.cpp | 207 ++++++++++++++++++++++++++++++++++ yoga/YGFloatOptional.cpp | 2 +- yoga/YGFloatOptional.h | 2 +- 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 tests/YGFloatOptionalTest.cpp diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp new file mode 100644 index 00000000..f2995747 --- /dev/null +++ b/tests/YGFloatOptionalTest.cpp @@ -0,0 +1,207 @@ +/** + * Copyright (c) Facebook, Inc. and its 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 +#include + +static const auto empty = YGFloatOptional{}; +static const auto zero = YGFloatOptional{0.0f}; +static const auto one = YGFloatOptional{1.0f}; +static const auto positive = YGFloatOptional{1234.5f}; +static const auto negative = YGFloatOptional{-9876.5f}; + +TEST(YGFloatOptional, value) { + ASSERT_EQ(zero.getValue(), 0.0f); + ASSERT_EQ(one.getValue(), 1.0f); + ASSERT_EQ(positive.getValue(), 1234.5f); + ASSERT_EQ(negative.getValue(), -9876.5f); + + ASSERT_TRUE(empty.isUndefined()); + ASSERT_FALSE(zero.isUndefined()); + ASSERT_FALSE(one.isUndefined()); + ASSERT_FALSE(positive.isUndefined()); + ASSERT_FALSE(negative.isUndefined()); +} + +TEST(YGFloatOptional, equality) { + ASSERT_TRUE(empty == empty); + ASSERT_TRUE(empty == YGUndefined); + ASSERT_FALSE(empty == zero); + ASSERT_FALSE(empty == negative); + ASSERT_FALSE(empty == 12.3f); + + ASSERT_TRUE(zero == zero); + ASSERT_TRUE(zero == 0.0f); + ASSERT_FALSE(zero == positive); + ASSERT_FALSE(zero == -5555.5f); + + ASSERT_TRUE(one == one); + ASSERT_TRUE(one == 1.0f); + ASSERT_FALSE(one == positive); + + ASSERT_TRUE(positive == positive); + ASSERT_TRUE(positive == positive.getValue()); + ASSERT_FALSE(positive == one); + + ASSERT_TRUE(negative == negative); + ASSERT_TRUE(negative == negative.getValue()); + ASSERT_FALSE(negative == zero); +} + +TEST(YGFloatOptional, inequality) { + ASSERT_FALSE(empty != empty); + ASSERT_FALSE(empty != YGUndefined); + ASSERT_TRUE(empty != zero); + ASSERT_TRUE(empty != negative); + ASSERT_TRUE(empty != 12.3f); + + ASSERT_FALSE(zero != zero); + ASSERT_FALSE(zero != 0.0f); + ASSERT_TRUE(zero != positive); + ASSERT_TRUE(zero != -5555.5f); + + ASSERT_FALSE(one != one); + ASSERT_FALSE(one != 1.0f); + ASSERT_TRUE(one != positive); + + ASSERT_FALSE(positive != positive); + ASSERT_FALSE(positive != positive.getValue()); + ASSERT_TRUE(positive != one); + + ASSERT_FALSE(negative != negative); + ASSERT_FALSE(negative != negative.getValue()); + ASSERT_TRUE(negative != zero); +} + +TEST(YGFloatOptional, greater_than_with_undefined) { + ASSERT_FALSE(empty > empty); + ASSERT_FALSE(empty > zero); + ASSERT_FALSE(empty > one); + ASSERT_FALSE(empty > positive); + ASSERT_FALSE(empty > negative); + ASSERT_FALSE(zero > empty); + ASSERT_FALSE(one > empty); + ASSERT_FALSE(positive > empty); + ASSERT_FALSE(negative > empty); +} + +TEST(YGFloatOptional, greater_than) { + ASSERT_TRUE(zero > negative); + ASSERT_FALSE(zero > zero); + ASSERT_FALSE(zero > positive); + ASSERT_FALSE(zero > one); + + ASSERT_TRUE(one > negative); + ASSERT_TRUE(one > zero); + ASSERT_FALSE(one > positive); + + ASSERT_TRUE(negative > YGFloatOptional{-INFINITY}); +} + +TEST(YGFloatOptional, less_than_with_undefined) { + ASSERT_FALSE(empty < empty); + ASSERT_FALSE(zero < empty); + ASSERT_FALSE(one < empty); + ASSERT_FALSE(positive < empty); + ASSERT_FALSE(negative < empty); + ASSERT_FALSE(empty < zero); + ASSERT_FALSE(empty < one); + ASSERT_FALSE(empty < positive); + ASSERT_FALSE(empty < negative); +} + +TEST(YGFloatOptional, less_than) { + ASSERT_TRUE(negative < zero); + ASSERT_FALSE(zero < zero); + ASSERT_FALSE(positive < zero); + ASSERT_FALSE(one < zero); + + ASSERT_TRUE(negative < one); + ASSERT_TRUE(zero < one); + ASSERT_FALSE(positive < one); + + ASSERT_TRUE(YGFloatOptional{-INFINITY} < negative); +} + +TEST(YGFloatOptional, greater_than_equals_with_undefined) { + ASSERT_TRUE(empty >= empty); + ASSERT_FALSE(empty >= zero); + ASSERT_FALSE(empty >= one); + ASSERT_FALSE(empty >= positive); + ASSERT_FALSE(empty >= negative); + ASSERT_FALSE(zero >= empty); + ASSERT_FALSE(one >= empty); + ASSERT_FALSE(positive >= empty); + ASSERT_FALSE(negative >= empty); +} + +TEST(YGFloatOptional, greater_than_equals) { + ASSERT_TRUE(zero >= negative); + ASSERT_TRUE(zero >= zero); + ASSERT_FALSE(zero >= positive); + ASSERT_FALSE(zero >= one); + + ASSERT_TRUE(one >= negative); + ASSERT_TRUE(one >= zero); + ASSERT_FALSE(one >= positive); + + ASSERT_TRUE(negative >= YGFloatOptional{-INFINITY}); +} + +TEST(YGFloatOptional, less_than_equals_with_undefined) { + ASSERT_TRUE(empty <= empty); + ASSERT_FALSE(zero <= empty); + ASSERT_FALSE(one <= empty); + ASSERT_FALSE(positive <= empty); + ASSERT_FALSE(negative <= empty); + ASSERT_FALSE(empty <= zero); + ASSERT_FALSE(empty <= one); + ASSERT_FALSE(empty <= positive); + ASSERT_FALSE(empty <= negative); +} + +TEST(YGFloatOptional, less_than_equals) { + ASSERT_TRUE(negative <= zero); + ASSERT_TRUE(zero <= zero); + ASSERT_FALSE(positive <= zero); + ASSERT_FALSE(one <= zero); + + ASSERT_TRUE(negative <= one); + ASSERT_TRUE(zero <= one); + ASSERT_FALSE(positive <= one); + + ASSERT_TRUE(YGFloatOptional{-INFINITY} <= negative); +} + +TEST(YGFloatOptional, addition) { + auto n = negative.getValue(); + auto p = positive.getValue(); + + ASSERT_EQ(zero + one, one); + ASSERT_EQ(negative + positive, YGFloatOptional{n + p}); + ASSERT_EQ(empty + zero, empty); + ASSERT_EQ(empty + empty, empty); + ASSERT_EQ(negative + empty, empty); +} + +TEST(YGFloatOptionalTest, YGFloatOptionalMax) { + ASSERT_EQ(YGFloatOptionalMax(empty, empty), empty); + ASSERT_EQ(YGFloatOptionalMax(empty, positive), positive); + ASSERT_EQ(YGFloatOptionalMax(negative, empty), negative); + ASSERT_EQ(YGFloatOptionalMax(negative, YGFloatOptional{-INFINITY}), negative); + ASSERT_EQ( + YGFloatOptionalMax(YGFloatOptional{1.0f}, YGFloatOptional{1.125f}), + YGFloatOptional{1.125f}); +} + +TEST(YGFloatOptionalTest, YGUnwrapFloatOptional) { + ASSERT_TRUE(YGFloatIsUndefined(YGUnwrapFloatOptional(empty))); + ASSERT_EQ(YGUnwrapFloatOptional(zero), 0.0f); + ASSERT_EQ(YGUnwrapFloatOptional(YGFloatOptional{123456.78f}), 123456.78f); +} diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp index d023dccb..da7b8ce8 100644 --- a/yoga/YGFloatOptional.cpp +++ b/yoga/YGFloatOptional.cpp @@ -53,7 +53,7 @@ bool YGFloatOptional::operator!=(float val) const { return !(*this == val); } -YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) { +YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) const { if (!isUndefined_ && !op.isUndefined_) { return YGFloatOptional(value_ + op.value_); } diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 07fbb64b..6f4af241 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -30,7 +30,7 @@ struct YGFloatOptional { return isUndefined_; } - YGFloatOptional operator+(const YGFloatOptional& op); + YGFloatOptional operator+(const YGFloatOptional& op) const; bool operator>(const YGFloatOptional& op) const; bool operator<(const YGFloatOptional& op) const; bool operator>=(const YGFloatOptional& op) const; -- 2.50.1.windows.1 From 6bdd39d0ed84e101112b31243bd3bcb60ff46ba1 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:30 -0800 Subject: [PATCH 31/53] Store `YGFloatOptional` in 32 bits Summary: @public After removing `-ffast-math`, `NaN` can again be used to represent `undefined`. That allows us to remove the additional flag from `YGFloatOptional`, and reduce memory usage. Reviewed By: SidharthGuglani Differential Revision: D13439611 fbshipit-source-id: 93e90f72f0415edb228b4e7d145e1fae35cc6b43 --- tests/YGFloatOptionalTest.cpp | 10 +++---- yoga/YGFloatOptional.cpp | 53 +++++++++-------------------------- yoga/YGFloatOptional.h | 32 +++++++++------------ yoga/YGNode.cpp | 2 +- 4 files changed, 34 insertions(+), 63 deletions(-) diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp index f2995747..3c73b0ba 100644 --- a/tests/YGFloatOptionalTest.cpp +++ b/tests/YGFloatOptionalTest.cpp @@ -10,11 +10,11 @@ #include #include -static const auto empty = YGFloatOptional{}; -static const auto zero = YGFloatOptional{0.0f}; -static const auto one = YGFloatOptional{1.0f}; -static const auto positive = YGFloatOptional{1234.5f}; -static const auto negative = YGFloatOptional{-9876.5f}; +constexpr auto empty = YGFloatOptional{}; +constexpr auto zero = YGFloatOptional{0.0f}; +constexpr auto one = YGFloatOptional{1.0f}; +constexpr auto positive = YGFloatOptional{1234.5f}; +constexpr auto negative = YGFloatOptional{-9876.5f}; TEST(YGFloatOptional, value) { ASSERT_EQ(zero.getValue(), 0.0f); diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp index da7b8ce8..0bf89f29 100644 --- a/yoga/YGFloatOptional.cpp +++ b/yoga/YGFloatOptional.cpp @@ -7,23 +7,13 @@ #include "YGFloatOptional.h" #include #include -#include "Yoga.h" #include "Yoga-internal.h" +#include "Yoga.h" using namespace facebook; -YGFloatOptional::YGFloatOptional(float value) { - if (yoga::isUndefined(value)) { - isUndefined_ = true; - value_ = 0; - } else { - value_ = value; - isUndefined_ = false; - } -} - float YGFloatOptional::getValue() const { - if (isUndefined_) { + if (isUndefined()) { // Abort, accessing a value of an undefined float optional std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; std::exit(EXIT_FAILURE); @@ -31,53 +21,38 @@ float YGFloatOptional::getValue() const { return value_; } -bool YGFloatOptional::operator==(const YGFloatOptional& op) const { - if (isUndefined_ == op.isUndefined()) { - return isUndefined_ || value_ == op.getValue(); - } - return false; +bool YGFloatOptional::operator==(YGFloatOptional op) const { + return value_ == op.value_ || (isUndefined() && op.isUndefined()); } -bool YGFloatOptional::operator!=(const YGFloatOptional& op) const { +bool YGFloatOptional::operator!=(YGFloatOptional op) const { return !(*this == op); } bool YGFloatOptional::operator==(float val) const { - if (yoga::isUndefined(val) == isUndefined_) { - return isUndefined_ || val == value_; - } - return false; + return value_ == val || (isUndefined() && yoga::isUndefined(val)); } bool YGFloatOptional::operator!=(float val) const { return !(*this == val); } -YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) const { - if (!isUndefined_ && !op.isUndefined_) { - return YGFloatOptional(value_ + op.value_); - } - return YGFloatOptional(); +YGFloatOptional YGFloatOptional::operator+(YGFloatOptional op) const { + return YGFloatOptional{value_ + op.value_}; } -bool YGFloatOptional::operator>(const YGFloatOptional& op) const { - if (isUndefined_ || op.isUndefined_) { - return false; - } +bool YGFloatOptional::operator>(YGFloatOptional op) const { return value_ > op.value_; } -bool YGFloatOptional::operator<(const YGFloatOptional& op) const { - if (isUndefined_ || op.isUndefined_) { - return false; - } +bool YGFloatOptional::operator<(YGFloatOptional op) const { return value_ < op.value_; } -bool YGFloatOptional::operator>=(const YGFloatOptional& op) const { - return *this == op || *this > op; +bool YGFloatOptional::operator>=(YGFloatOptional op) const { + return *this > op || *this == op; } -bool YGFloatOptional::operator<=(const YGFloatOptional& op) const { - return *this == op || *this < op; +bool YGFloatOptional::operator<=(YGFloatOptional op) const { + return *this < op || *this == op; } diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 6f4af241..7b573d38 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -6,37 +6,33 @@ */ #pragma once +#include +#include + struct YGFloatOptional { private: - float value_ = 0; - bool isUndefined_ = true; + float value_ = std::numeric_limits::quiet_NaN(); public: - explicit YGFloatOptional(float value); - YGFloatOptional() = default; + explicit constexpr YGFloatOptional(float value) : value_(value) {} + constexpr YGFloatOptional() = default; // Program will terminate if the value of an undefined is accessed. Please // make sure to check if the optional is defined before calling this function. // To check if float optional is defined, use `isUndefined()`. float getValue() const; - // Sets the value of float optional, and thus isUndefined is assigned false. - void setValue(float val) { - value_ = val; - isUndefined_ = false; - } - bool isUndefined() const { - return isUndefined_; + return std::isnan(value_); } - YGFloatOptional operator+(const YGFloatOptional& op) const; - bool operator>(const YGFloatOptional& op) const; - bool operator<(const YGFloatOptional& op) const; - bool operator>=(const YGFloatOptional& op) const; - bool operator<=(const YGFloatOptional& op) const; - bool operator==(const YGFloatOptional& op) const; - bool operator!=(const YGFloatOptional& op) const; + YGFloatOptional operator+(YGFloatOptional op) const; + bool operator>(YGFloatOptional op) const; + bool operator<(YGFloatOptional op) const; + bool operator>=(YGFloatOptional op) const; + bool operator<=(YGFloatOptional op) const; + bool operator==(YGFloatOptional op) const; + bool operator!=(YGFloatOptional op) const; bool operator==(float val) const; bool operator!=(float val) const; diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 1694692c..04c3c7f6 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -211,7 +211,7 @@ YGFloatOptional YGNode::relativePosition( YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize); if (!trailingPosition.isUndefined()) { - trailingPosition.setValue(-1 * trailingPosition.getValue()); + trailingPosition = YGFloatOptional{-1 * trailingPosition.getValue()}; } return trailingPosition; } -- 2.50.1.windows.1 From aaa018bbea9ce3361120f13c1d614e752827c2f7 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:30 -0800 Subject: [PATCH 32/53] Remove `YGUnwrapFloatOptional` Summary: Replaces `YGUnwrapFloatOptional` with `YGFloatOptional::unwrap`. This leads to more idiomatic C++, and to less function call nesting, thus increasing readability. Reviewed By: SidharthGuglani Differential Revision: D13439604 fbshipit-source-id: 33b43c08d725c253c359959e7cbbd83fd6bd9ba4 --- tests/YGFloatOptionalTest.cpp | 8 +- yoga/Utils.cpp | 4 - yoga/Utils.h | 5 - yoga/YGFloatOptional.h | 5 + yoga/YGNode.cpp | 14 +- yoga/Yoga.cpp | 376 ++++++++++++++++++---------------- 6 files changed, 211 insertions(+), 201 deletions(-) diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp index 3c73b0ba..38c7ebb3 100644 --- a/tests/YGFloatOptionalTest.cpp +++ b/tests/YGFloatOptionalTest.cpp @@ -200,8 +200,8 @@ TEST(YGFloatOptionalTest, YGFloatOptionalMax) { YGFloatOptional{1.125f}); } -TEST(YGFloatOptionalTest, YGUnwrapFloatOptional) { - ASSERT_TRUE(YGFloatIsUndefined(YGUnwrapFloatOptional(empty))); - ASSERT_EQ(YGUnwrapFloatOptional(zero), 0.0f); - ASSERT_EQ(YGUnwrapFloatOptional(YGFloatOptional{123456.78f}), 123456.78f); +TEST(YGFloatOptionalTest, unwrap) { + ASSERT_TRUE(YGFloatIsUndefined(empty.unwrap())); + ASSERT_EQ(zero.unwrap(), 0.0f); + ASSERT_EQ(YGFloatOptional{123456.78f}.unwrap(), 123456.78f); } diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 74cc38c9..331cb660 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -55,10 +55,6 @@ float YGFloatSanitize(const float val) { return yoga::isUndefined(val) ? 0 : val; } -float YGUnwrapFloatOptional(const YGFloatOptional& op) { - return op.isUndefined() ? YGUndefined : op.getValue(); -} - YGFloatOptional YGFloatOptionalMax( const YGFloatOptional& op1, const YGFloatOptional& op2) { diff --git a/yoga/Utils.h b/yoga/Utils.h index d007ff54..e5e20ba3 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -82,11 +82,6 @@ bool YGFloatArrayEqual( // This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise float YGFloatSanitize(const float val); -// This function unwraps optional and returns YGUndefined if not defined or -// op.value otherwise -// TODO: Get rid off this function -float YGUnwrapFloatOptional(const YGFloatOptional& op); - YGFlexDirection YGFlexDirectionCross( const YGFlexDirection flexDirection, const YGDirection direction); diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 7b573d38..56bc8557 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -22,6 +22,11 @@ struct YGFloatOptional { // To check if float optional is defined, use `isUndefined()`. float getValue() const; + // returns the wrapped value, or a value x with YGIsUndefined(x) == true + float unwrap() const { + return value_; + } + bool isUndefined() const { return std::isnan(value_); } diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 04c3c7f6..d930c51a 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -236,20 +236,18 @@ void YGNode::setPosition( relativePosition(crossAxis, crossSize); setLayoutPosition( - YGUnwrapFloatOptional( - getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain), + (getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), leading[mainAxis]); setLayoutPosition( - YGUnwrapFloatOptional( - getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain), + (getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), trailing[mainAxis]); setLayoutPosition( - YGUnwrapFloatOptional( - getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross), + (getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross) + .unwrap(), leading[crossAxis]); setLayoutPosition( - YGUnwrapFloatOptional( - getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross), + (getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross) + .unwrap(), trailing[crossAxis]); } diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 246e0f41..8db18e9e 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1096,9 +1096,9 @@ static inline float YGNodePaddingAndBorderForAxis( const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { - return YGUnwrapFloatOptional( - node->getLeadingPaddingAndBorder(axis, widthSize) + - node->getTrailingPaddingAndBorder(axis, widthSize)); + return (node->getLeadingPaddingAndBorder(axis, widthSize) + + node->getTrailingPaddingAndBorder(axis, widthSize)) + .unwrap(); } static inline YGAlign YGNodeAlignItem( @@ -1180,9 +1180,9 @@ static inline float YGNodeDimWithMargin( const YGFlexDirection axis, const float widthSize) { return node->getLayout().measuredDimensions[dim[axis]] + - YGUnwrapFloatOptional( - node->getLeadingMargin(axis, widthSize) + - node->getTrailingMargin(axis, widthSize)); + (node->getLeadingMargin(axis, widthSize) + + node->getTrailingMargin(axis, widthSize)) + .unwrap(); } static inline bool YGNodeIsStyleDimDefined( @@ -1249,8 +1249,7 @@ static inline float YGNodeBoundAxis( const float axisSize, const float widthSize) { return YGFloatMax( - YGUnwrapFloatOptional( - YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize)), + YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize).unwrap(), YGNodePaddingAndBorderForAxis(node, axis, widthSize)); } @@ -1357,22 +1356,24 @@ static void YGNodeComputeFlexBasisForChild( childWidthMeasureMode = YGMeasureModeUndefined; childHeightMeasureMode = YGMeasureModeUndefined; - auto marginRow = YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - auto marginColumn = YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + auto marginRow = + child->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); + auto marginColumn = + child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); if (isRowStyleDimDefined) { childWidth = - YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionWidth), ownerWidth)) + + YGResolveValue( + child->getResolvedDimension(YGDimensionWidth), ownerWidth) + .unwrap() + marginRow; childWidthMeasureMode = YGMeasureModeExactly; } if (isColumnStyleDimDefined) { childHeight = - YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionHeight), ownerHeight)) + + YGResolveValue( + child->getResolvedDimension(YGDimensionHeight), ownerHeight) + .unwrap() + marginColumn; childHeightMeasureMode = YGMeasureModeExactly; } @@ -1500,14 +1501,14 @@ static void YGNodeAbsoluteLayoutChild( YGMeasureMode childWidthMeasureMode = YGMeasureModeUndefined; YGMeasureMode childHeightMeasureMode = YGMeasureModeUndefined; - auto marginRow = - YGUnwrapFloatOptional(child->getMarginForAxis(YGFlexDirectionRow, width)); - auto marginColumn = YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionColumn, width)); + auto marginRow = child->getMarginForAxis(YGFlexDirectionRow, width).unwrap(); + auto marginColumn = + child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap(); if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { - childWidth = YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionWidth), width)) + + childWidth = + YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width) + .unwrap() + marginRow; } else { // If the child doesn't have a specified width, compute the width based @@ -1518,17 +1519,18 @@ static void YGNodeAbsoluteLayoutChild( childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - (node->getLeadingBorder(YGFlexDirectionRow) + node->getTrailingBorder(YGFlexDirectionRow)) - - YGUnwrapFloatOptional( - child->getLeadingPosition(YGFlexDirectionRow, width) + - child->getTrailingPosition(YGFlexDirectionRow, width)); + (child->getLeadingPosition(YGFlexDirectionRow, width) + + child->getTrailingPosition(YGFlexDirectionRow, width)) + .unwrap(); childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); } } if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { - childHeight = YGUnwrapFloatOptional(YGResolveValue( - child->getResolvedDimension(YGDimensionHeight), height)) + + childHeight = + YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height) + .unwrap() + marginColumn; } else { // If the child doesn't have a specified height, compute the height @@ -1536,13 +1538,12 @@ static void YGNodeAbsoluteLayoutChild( // offsets if they're defined. if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && child->isTrailingPosDefined(YGFlexDirectionColumn)) { - childHeight = - node->getLayout().measuredDimensions[YGDimensionHeight] - + childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - (node->getLeadingBorder(YGFlexDirectionColumn) + node->getTrailingBorder(YGFlexDirectionColumn)) - - YGUnwrapFloatOptional( - child->getLeadingPosition(YGFlexDirectionColumn, height) + - child->getTrailingPosition(YGFlexDirectionColumn, height)); + (child->getLeadingPosition(YGFlexDirectionColumn, height) + + child->getTrailingPosition(YGFlexDirectionColumn, height)) + .unwrap(); childHeight = YGNodeBoundAxis( child, YGFlexDirectionColumn, childHeight, height, width); } @@ -1597,11 +1598,9 @@ static void YGNodeAbsoluteLayoutChild( "abs-measure", config); childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + - YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionRow, width)); + child->getMarginForAxis(YGFlexDirectionRow, width).unwrap(); childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional( - child->getMarginForAxis(YGFlexDirectionColumn, width)); + child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap(); } YGLayoutNodeInternal( @@ -1623,9 +1622,9 @@ static void YGNodeAbsoluteLayoutChild( node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]] - node->getTrailingBorder(mainAxis) - - YGUnwrapFloatOptional(child->getTrailingMargin(mainAxis, width)) - - YGUnwrapFloatOptional(child->getTrailingPosition( - mainAxis, isMainAxisRow ? width : height)), + child->getTrailingMargin(mainAxis, width).unwrap() - + child->getTrailingPosition(mainAxis, isMainAxisRow ? width : height) + .unwrap(), leading[mainAxis]); } else if ( !child->isLeadingPositionDefined(mainAxis) && @@ -1650,9 +1649,10 @@ static void YGNodeAbsoluteLayoutChild( node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]] - node->getTrailingBorder(crossAxis) - - YGUnwrapFloatOptional(child->getTrailingMargin(crossAxis, width)) - - YGUnwrapFloatOptional(child->getTrailingPosition( - crossAxis, isMainAxisRow ? height : width)), + child->getTrailingMargin(crossAxis, width).unwrap() - + child + ->getTrailingPosition(crossAxis, isMainAxisRow ? height : width) + .unwrap(), leading[crossAxis]); } else if ( @@ -1691,10 +1691,10 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis( node, YGFlexDirectionColumn, availableWidth); - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, availableWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, availableWidth)); + const float marginAxisRow = + node->getMarginForAxis(YGFlexDirectionRow, availableWidth).unwrap(); + const float marginAxisColumn = + node->getMarginForAxis(YGFlexDirectionColumn, availableWidth).unwrap(); // We want to make sure we don't call measure with negative size const float innerWidth = YGFloatIsUndefined(availableWidth) @@ -1769,10 +1769,10 @@ static void YGNodeEmptyContainerSetMeasuredDimensions( YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + const float marginAxisRow = + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); + const float marginAxisColumn = + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); node->setLayoutMeasuredDimension( YGNodeBoundAxis( @@ -1813,10 +1813,10 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) || (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly)) { - auto marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); - auto marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + auto marginAxisColumn = + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); + auto marginAxisRow = + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); node->setLayoutMeasuredDimension( YGNodeBoundAxis( @@ -1872,8 +1872,7 @@ static float YGNodeCalculateAvailableInnerDim( YGDimension dimension = YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight; - const float margin = - YGUnwrapFloatOptional(node->getMarginForAxis(direction, ownerDim)); + const float margin = node->getMarginForAxis(direction, ownerDim).unwrap(); const float paddingAndBorder = YGNodePaddingAndBorderForAxis(node, direction, ownerDim); @@ -1978,9 +1977,10 @@ static float YGNodeComputeFlexBasisForChildren( config); } - totalOuterFlexBasis += YGUnwrapFloatOptional( - child->getLayout().computedFlexBasis + - child->getMarginForAxis(mainAxis, availableInnerWidth)); + totalOuterFlexBasis += + (child->getLayout().computedFlexBasis + + child->getMarginForAxis(mainAxis, availableInnerWidth)) + .unwrap(); } return totalOuterFlexBasis; @@ -2015,14 +2015,15 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( continue; } child->setLineIndex(lineCount); - const float childMarginMainAxis = YGUnwrapFloatOptional( - child->getMarginForAxis(mainAxis, availableInnerWidth)); + const float childMarginMainAxis = + child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap(); const float flexBasisWithMinAndMaxConstraints = - YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + YGNodeBoundAxisWithinMinAndMax( child, mainAxis, - YGUnwrapFloatOptional(child->getLayout().computedFlexBasis), - mainAxisownerSize)); + child->getLayout().computedFlexBasis.unwrap(), + mainAxisownerSize) + .unwrap(); // If this is a multi-line flow and this item pushes us over the // available size, we've @@ -2048,7 +2049,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( // child dimension. flexAlgoRowMeasurement.totalFlexShrinkScaledFactors += -child->resolveFlexShrink() * - YGUnwrapFloatOptional(child->getLayout().computedFlexBasis); + child->getLayout().computedFlexBasis.unwrap(); } flexAlgoRowMeasurement.relativeChildren.push_back(child); @@ -2095,12 +2096,13 @@ static float YGDistributeFreeSpaceSecondPass( const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - YGUnwrapFloatOptional( - currentRelativeChild->getLayout().computedFlexBasis), - mainAxisownerSize)); + childFlexBasis = + YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + currentRelativeChild->getLayout().computedFlexBasis.unwrap(), + mainAxisownerSize) + .unwrap(); float updatedMainSize = childFlexBasis; if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && @@ -2150,10 +2152,12 @@ static float YGDistributeFreeSpaceSecondPass( deltaFreeSpace += updatedMainSize - childFlexBasis; - const float marginMain = YGUnwrapFloatOptional( - currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth)); - const float marginCross = YGUnwrapFloatOptional( - currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth)); + const float marginMain = + currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth) + .unwrap(); + const float marginCross = + currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth) + .unwrap(); float childCrossSize; float childMainSize = updatedMainSize + marginMain; @@ -2189,9 +2193,10 @@ static float YGDistributeFreeSpaceSecondPass( : YGMeasureModeAtMost; } else { childCrossSize = - YGUnwrapFloatOptional(YGResolveValue( + YGResolveValue( currentRelativeChild->getResolvedDimension(dim[crossAxis]), - availableInnerCrossDim)) + + availableInnerCrossDim) + .unwrap() + marginCross; const bool isLoosePercentageMeasurement = currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit == @@ -2271,12 +2276,13 @@ static void YGDistributeFreeSpaceFirstPass( float deltaFreeSpace = 0; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - float childFlexBasis = YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - YGUnwrapFloatOptional( - currentRelativeChild->getLayout().computedFlexBasis), - mainAxisownerSize)); + float childFlexBasis = + YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + currentRelativeChild->getLayout().computedFlexBasis.unwrap(), + mainAxisownerSize) + .unwrap(); if (collectedFlexItemsValues.remainingFreeSpace < 0) { flexShrinkScaledFactor = @@ -2427,10 +2433,10 @@ static void YGJustifyMainAxis( const float availableInnerWidth, const bool performLayout) { const YGStyle& style = node->getStyle(); - const float leadingPaddingAndBorderMain = YGUnwrapFloatOptional( - node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)); - const float trailingPaddingAndBorderMain = YGUnwrapFloatOptional( - node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)); + const float leadingPaddingAndBorderMain = + node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); + const float trailingPaddingAndBorderMain = + node->getTrailingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); // If we are using "at most" rules in the main axis, make sure that // remainingFreeSpace is 0 when min main dimension is not given if (measureModeMainDim == YGMeasureModeAtMost && @@ -2446,8 +2452,8 @@ static void YGJustifyMainAxis( // `minAvailableMainDim` denotes minimum available space in which child // can be laid out, it will exclude space consumed by padding and border. const float minAvailableMainDim = - YGUnwrapFloatOptional(YGResolveValue( - style.minDimensions[dim[mainAxis]], mainAxisownerSize)) - + YGResolveValue(style.minDimensions[dim[mainAxis]], mainAxisownerSize) + .unwrap() - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; const float occupiedSpaceByChildNodes = availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace; @@ -2537,11 +2543,10 @@ static void YGJustifyMainAxis( // defined, we override the position to whatever the user said // (and margin/border). child->setLayoutPosition( - YGUnwrapFloatOptional( - child->getLeadingPosition(mainAxis, availableInnerMainDim)) + + child->getLeadingPosition(mainAxis, availableInnerMainDim) + .unwrap() + node->getLeadingBorder(mainAxis) + - YGUnwrapFloatOptional( - child->getLeadingMargin(mainAxis, availableInnerWidth)), + child->getLeadingMargin(mainAxis, availableInnerWidth).unwrap(), pos[mainAxis]); } } else { @@ -2575,9 +2580,8 @@ static void YGJustifyMainAxis( // they weren't computed. This means we can't call // YGNodeDimWithMargin. collectedFlexItemsValues.mainDim += betweenMainDim + - YGUnwrapFloatOptional(child->getMarginForAxis( - mainAxis, availableInnerWidth)) + - YGUnwrapFloatOptional(childLayout.computedFlexBasis); + child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap() + + childLayout.computedFlexBasis.unwrap(); collectedFlexItemsValues.crossDim = availableInnerCrossDim; } else { // The main dimension is the sum of all the elements dimension plus @@ -2589,12 +2593,16 @@ static void YGJustifyMainAxis( // If the child is baseline aligned then the cross dimension is // calculated by adding maxAscent and maxDescent from the baseline. const float ascent = YGBaseline(child) + - YGUnwrapFloatOptional(child->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth)); + child + ->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth) + .unwrap(); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional(child->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth)) - + child + ->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth) + .unwrap() - ascent; maxAscentForCurrentLine = @@ -2747,20 +2755,16 @@ static void YGNodelayoutImpl( YGResolveFlexDirection(YGFlexDirectionColumn, direction); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getLeadingMargin(flexRowDirection, ownerWidth)), + node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap(), YGEdgeStart); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getTrailingMargin(flexRowDirection, ownerWidth)), + node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap(), YGEdgeEnd); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getLeadingMargin(flexColumnDirection, ownerWidth)), + node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap(), YGEdgeTop); node->setLayoutMargin( - YGUnwrapFloatOptional( - node->getTrailingMargin(flexColumnDirection, ownerWidth)), + node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap(), YGEdgeBottom); node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), YGEdgeStart); @@ -2770,20 +2774,16 @@ static void YGNodelayoutImpl( node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getLeadingPadding(flexRowDirection, ownerWidth)), + node->getLeadingPadding(flexRowDirection, ownerWidth).unwrap(), YGEdgeStart); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getTrailingPadding(flexRowDirection, ownerWidth)), + node->getTrailingPadding(flexRowDirection, ownerWidth).unwrap(), YGEdgeEnd); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getLeadingPadding(flexColumnDirection, ownerWidth)), + node->getLeadingPadding(flexColumnDirection, ownerWidth).unwrap(), YGEdgeTop); node->setLayoutPadding( - YGUnwrapFloatOptional( - node->getTrailingPadding(flexColumnDirection, ownerWidth)), + node->getTrailingPadding(flexColumnDirection, ownerWidth).unwrap(), YGEdgeBottom); if (node->getMeasure() != nullptr) { @@ -2841,8 +2841,8 @@ static void YGNodelayoutImpl( const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth; - const float leadingPaddingAndBorderCross = YGUnwrapFloatOptional( - node->getLeadingPaddingAndBorder(crossAxis, ownerWidth)); + const float leadingPaddingAndBorderCross = + node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); const float paddingAndBorderAxisCross = @@ -2858,26 +2858,30 @@ static void YGNodelayoutImpl( const float paddingAndBorderAxisColumn = isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + const float marginAxisRow = + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); + const float marginAxisColumn = + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); const float minInnerWidth = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)) - + YGResolveValue( + node->getStyle().minDimensions[YGDimensionWidth], ownerWidth) + .unwrap() - paddingAndBorderAxisRow; const float maxInnerWidth = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)) - + YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth) + .unwrap() - paddingAndBorderAxisRow; const float minInnerHeight = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)) - + YGResolveValue( + node->getStyle().minDimensions[YGDimensionHeight], ownerHeight) + .unwrap() - paddingAndBorderAxisColumn; const float maxInnerHeight = - YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)) - + YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight) + .unwrap() - paddingAndBorderAxisColumn; const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; @@ -3088,11 +3092,11 @@ static void YGNodelayoutImpl( child->isLeadingPositionDefined(crossAxis); if (isChildLeadingPosDefined) { child->setLayoutPosition( - YGUnwrapFloatOptional(child->getLeadingPosition( - crossAxis, availableInnerCrossDim)) + + child->getLeadingPosition(crossAxis, availableInnerCrossDim) + .unwrap() + node->getLeadingBorder(crossAxis) + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + child->getLeadingMargin(crossAxis, availableInnerWidth) + .unwrap(), pos[crossAxis]); } // If leading position is not defined or calculations result in Nan, @@ -3101,8 +3105,8 @@ static void YGNodelayoutImpl( YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) { child->setLayoutPosition( node->getLeadingBorder(crossAxis) + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + child->getLeadingMargin(crossAxis, availableInnerWidth) + .unwrap(), pos[crossAxis]); } } else { @@ -3128,16 +3132,17 @@ static void YGNodelayoutImpl( child->getLayout().measuredDimensions[dim[mainAxis]]; float childCrossSize = !child->getStyle().aspectRatio.isUndefined() - ? ((YGUnwrapFloatOptional(child->getMarginForAxis( - crossAxis, availableInnerWidth)) + + ? child->getMarginForAxis(crossAxis, availableInnerWidth) + .unwrap() + (isMainAxisRow ? childMainSize / child->getStyle().aspectRatio.getValue() : childMainSize * - child->getStyle().aspectRatio.getValue()))) + child->getStyle().aspectRatio.getValue()) : collectedFlexItemsValues.crossDim; - childMainSize += YGUnwrapFloatOptional( - child->getMarginForAxis(mainAxis, availableInnerWidth)); + childMainSize += + child->getMarginForAxis(mainAxis, availableInnerWidth) + .unwrap(); YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly; @@ -3279,17 +3284,21 @@ static void YGNodelayoutImpl( lineHeight = YGFloatMax( lineHeight, child->getLayout().measuredDimensions[dim[crossAxis]] + - YGUnwrapFloatOptional(child->getMarginForAxis( - crossAxis, availableInnerWidth))); + child->getMarginForAxis(crossAxis, availableInnerWidth) + .unwrap()); } if (YGNodeAlignItem(node, child) == YGAlignBaseline) { const float ascent = YGBaseline(child) + - YGUnwrapFloatOptional(child->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth)); + child + ->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth) + .unwrap(); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional(child->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth)) - + child + ->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth) + .unwrap() - ascent; maxAscentForCurrentLine = YGFloatMax(maxAscentForCurrentLine, ascent); @@ -3314,16 +3323,16 @@ static void YGNodelayoutImpl( case YGAlignFlexStart: { child->setLayoutPosition( currentLead + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + child->getLeadingMargin(crossAxis, availableInnerWidth) + .unwrap(), pos[crossAxis]); break; } case YGAlignFlexEnd: { child->setLayoutPosition( currentLead + lineHeight - - YGUnwrapFloatOptional(child->getTrailingMargin( - crossAxis, availableInnerWidth)) - + child->getTrailingMargin(crossAxis, availableInnerWidth) + .unwrap() - child->getLayout().measuredDimensions[dim[crossAxis]], pos[crossAxis]); break; @@ -3340,8 +3349,8 @@ static void YGNodelayoutImpl( case YGAlignStretch: { child->setLayoutPosition( currentLead + - YGUnwrapFloatOptional(child->getLeadingMargin( - crossAxis, availableInnerWidth)), + child->getLeadingMargin(crossAxis, availableInnerWidth) + .unwrap(), pos[crossAxis]); // Remeasure child with the line height as it as been only @@ -3351,15 +3360,15 @@ static void YGNodelayoutImpl( const float childWidth = isMainAxisRow ? (child->getLayout() .measuredDimensions[YGDimensionWidth] + - YGUnwrapFloatOptional(child->getMarginForAxis( - mainAxis, availableInnerWidth))) + child->getMarginForAxis(mainAxis, availableInnerWidth) + .unwrap()) : lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout() .measuredDimensions[YGDimensionHeight] + - YGUnwrapFloatOptional(child->getMarginForAxis( - crossAxis, availableInnerWidth))) + child->getMarginForAxis(crossAxis, availableInnerWidth) + .unwrap()) : lineHeight; if (!(YGFloatsEqual( @@ -3389,8 +3398,10 @@ static void YGNodelayoutImpl( case YGAlignBaseline: { child->setLayoutPosition( currentLead + maxAscentForCurrentLine - YGBaseline(child) + - YGUnwrapFloatOptional(child->getLeadingPosition( - YGFlexDirectionColumn, availableInnerCrossDim)), + child + ->getLeadingPosition( + YGFlexDirectionColumn, availableInnerCrossDim) + .unwrap(), YGEdgeTop); break; @@ -3446,8 +3457,9 @@ static void YGNodelayoutImpl( YGFloatMax( YGFloatMin( availableInnerMainDim + paddingAndBorderAxisMain, - YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( - node, mainAxis, maxLineMainDim, mainAxisownerSize))), + YGNodeBoundAxisWithinMinAndMax( + node, mainAxis, maxLineMainDim, mainAxisownerSize) + .unwrap()), paddingAndBorderAxisMain), dim[mainAxis]); } @@ -3473,11 +3485,12 @@ static void YGNodelayoutImpl( YGFloatMax( YGFloatMin( availableInnerCrossDim + paddingAndBorderAxisCross, - YGUnwrapFloatOptional(YGNodeBoundAxisWithinMinAndMax( + YGNodeBoundAxisWithinMinAndMax( node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross, - crossAxisownerSize))), + crossAxisownerSize) + .unwrap()), paddingAndBorderAxisCross), dim[crossAxis]); } @@ -3777,10 +3790,10 @@ bool YGLayoutNodeInternal( // expensive to measure, so it's worth avoiding redundant measurements if at // all possible. if (node->getMeasure() != nullptr) { - const float marginAxisRow = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); - const float marginAxisColumn = YGUnwrapFloatOptional( - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + const float marginAxisRow = + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); + const float marginAxisColumn = + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); // First, try to use the layout cache. if (YGNodeCanUseCachedMeasurement( @@ -4080,16 +4093,18 @@ void YGNodeCalculateLayout( float width = YGUndefined; YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { - width = YGUnwrapFloatOptional( - YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)); + width = + (YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) + .unwrap(); widthMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue( node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth) .isUndefined()) { - width = YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)); + width = YGResolveValue( + node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth) + .unwrap(); widthMeasureMode = YGMeasureModeAtMost; } else { width = ownerWidth; @@ -4100,18 +4115,19 @@ void YGNodeCalculateLayout( float height = YGUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { - height = YGUnwrapFloatOptional( - YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionColumn]), - ownerHeight) + - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)); + height = (YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionColumn]), + ownerHeight) + + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) + .unwrap(); heightMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue( node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight) .isUndefined()) { - height = YGUnwrapFloatOptional(YGResolveValue( - node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)); + height = YGResolveValue( + node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight) + .unwrap(); heightMeasureMode = YGMeasureModeAtMost; } else { height = ownerHeight; -- 2.50.1.windows.1 From 4b5ae211da43e0257684e24c413c5d9846811c70 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:30 -0800 Subject: [PATCH 33/53] Eliminate `YGFloatOptional::getValue()` Summary: @public Replace `YGFloatOptional::getValue()` with `YGFloatOptional::unwrap()`. `YGFloatOptional::getValue()` has the unfortunate property of calling `std::exit` if the wrapped value is undefined. Here, we eliminate the method, and just call `.unwrap()` everywhere. Reviewed By: shergin Differential Revision: D13439608 fbshipit-source-id: 5ae82b170537d0a10c301412567a7a66fd50bab4 --- tests/YGFloatOptionalTest.cpp | 21 +++++++++--------- yoga/Utils.cpp | 11 ++++----- yoga/Utils.h | 4 ++-- yoga/YGFloatOptional.cpp | 9 -------- yoga/YGFloatOptional.h | 5 ----- yoga/YGNode.cpp | 20 ++++++++--------- yoga/YGNodePrint.cpp | 2 +- yoga/YGStyle.cpp | 8 +++---- yoga/Yoga.cpp | 42 +++++++++++++++++------------------ 9 files changed, 55 insertions(+), 67 deletions(-) diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp index 38c7ebb3..3e231723 100644 --- a/tests/YGFloatOptionalTest.cpp +++ b/tests/YGFloatOptionalTest.cpp @@ -17,10 +17,11 @@ constexpr auto positive = YGFloatOptional{1234.5f}; constexpr auto negative = YGFloatOptional{-9876.5f}; TEST(YGFloatOptional, value) { - ASSERT_EQ(zero.getValue(), 0.0f); - ASSERT_EQ(one.getValue(), 1.0f); - ASSERT_EQ(positive.getValue(), 1234.5f); - ASSERT_EQ(negative.getValue(), -9876.5f); + ASSERT_TRUE(YGFloatIsUndefined(empty.unwrap())); + ASSERT_EQ(zero.unwrap(), 0.0f); + ASSERT_EQ(one.unwrap(), 1.0f); + ASSERT_EQ(positive.unwrap(), 1234.5f); + ASSERT_EQ(negative.unwrap(), -9876.5f); ASSERT_TRUE(empty.isUndefined()); ASSERT_FALSE(zero.isUndefined()); @@ -46,11 +47,11 @@ TEST(YGFloatOptional, equality) { ASSERT_FALSE(one == positive); ASSERT_TRUE(positive == positive); - ASSERT_TRUE(positive == positive.getValue()); + ASSERT_TRUE(positive == positive.unwrap()); ASSERT_FALSE(positive == one); ASSERT_TRUE(negative == negative); - ASSERT_TRUE(negative == negative.getValue()); + ASSERT_TRUE(negative == negative.unwrap()); ASSERT_FALSE(negative == zero); } @@ -71,11 +72,11 @@ TEST(YGFloatOptional, inequality) { ASSERT_TRUE(one != positive); ASSERT_FALSE(positive != positive); - ASSERT_FALSE(positive != positive.getValue()); + ASSERT_FALSE(positive != positive.unwrap()); ASSERT_TRUE(positive != one); ASSERT_FALSE(negative != negative); - ASSERT_FALSE(negative != negative.getValue()); + ASSERT_FALSE(negative != negative.unwrap()); ASSERT_TRUE(negative != zero); } @@ -180,8 +181,8 @@ TEST(YGFloatOptional, less_than_equals) { } TEST(YGFloatOptional, addition) { - auto n = negative.getValue(); - auto p = positive.getValue(); + auto n = negative.unwrap(); + auto p = positive.unwrap(); ASSERT_EQ(zero + one, one); ASSERT_EQ(negative + positive, YGFloatOptional{n + p}); diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 331cb660..2035fe00 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -55,11 +55,12 @@ float YGFloatSanitize(const float val) { return yoga::isUndefined(val) ? 0 : val; } -YGFloatOptional YGFloatOptionalMax( - const YGFloatOptional& op1, - const YGFloatOptional& op2) { - if (!op1.isUndefined() && !op2.isUndefined()) { - return op1.getValue() > op2.getValue() ? op1 : op2; +YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) { + if (op1 >= op2) { + return op1; + } + if (op2 > op1) { + return op2; } return op1.isUndefined() ? op2 : op1; } diff --git a/yoga/Utils.h b/yoga/Utils.h index e5e20ba3..9ea7a738 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -60,8 +60,8 @@ bool YGFloatsEqual(const float a, const float b); float YGFloatMax(const float a, const float b); YGFloatOptional YGFloatOptionalMax( - const YGFloatOptional& op1, - const YGFloatOptional& op2); + const YGFloatOptional op1, + const YGFloatOptional op2); float YGFloatMin(const float a, const float b); diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp index 0bf89f29..d202d4d5 100644 --- a/yoga/YGFloatOptional.cpp +++ b/yoga/YGFloatOptional.cpp @@ -12,15 +12,6 @@ using namespace facebook; -float YGFloatOptional::getValue() const { - if (isUndefined()) { - // Abort, accessing a value of an undefined float optional - std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; - std::exit(EXIT_FAILURE); - } - return value_; -} - bool YGFloatOptional::operator==(YGFloatOptional op) const { return value_ == op.value_ || (isUndefined() && op.isUndefined()); } diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index 56bc8557..b4974798 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -17,11 +17,6 @@ struct YGFloatOptional { explicit constexpr YGFloatOptional(float value) : value_(value) {} constexpr YGFloatOptional() = default; - // Program will terminate if the value of an undefined is accessed. Please - // make sure to check if the optional is defined before calling this function. - // To check if float optional is defined, use `isUndefined()`. - float getValue() const; - // returns the wrapped value, or a value x with YGIsUndefined(x) == true float unwrap() const { return value_; diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index d930c51a..3da72cb6 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -211,7 +211,7 @@ YGFloatOptional YGNode::relativePosition( YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize); if (!trailingPosition.isUndefined()) { - trailingPosition = YGFloatOptional{-1 * trailingPosition.getValue()}; + trailingPosition = YGFloatOptional{-1 * trailingPosition.unwrap()}; } return trailingPosition; } @@ -302,7 +302,7 @@ YGValue YGNode::resolveFlexBasisPtr() const { if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) { return flexBasis; } - if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { + if (!style_.flex.isUndefined() && style_.flex.unwrap() > 0.0f) { return config_->useWebDefaults ? YGValueAuto : YGValueZero; } return YGValueAuto; @@ -393,10 +393,10 @@ float YGNode::resolveFlexGrow() { return 0.0; } if (!style_.flexGrow.isUndefined()) { - return style_.flexGrow.getValue(); + return style_.flexGrow.unwrap(); } - if (!style_.flex.isUndefined() && style_.flex.getValue() > 0.0f) { - return style_.flex.getValue(); + if (!style_.flex.isUndefined() && style_.flex.unwrap() > 0.0f) { + return style_.flex.unwrap(); } return kDefaultFlexGrow; } @@ -406,11 +406,11 @@ float YGNode::resolveFlexShrink() { return 0.0; } if (!style_.flexShrink.isUndefined()) { - return style_.flexShrink.getValue(); + return style_.flexShrink.unwrap(); } if (!config_->useWebDefaults && !style_.flex.isUndefined() && - style_.flex.getValue() < 0.0f) { - return -style_.flex.getValue(); + style_.flex.unwrap() < 0.0f) { + return -style_.flex.unwrap(); } return config_->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink; } @@ -455,7 +455,7 @@ YGFloatOptional YGNode::getLeadingPadding( YGResolveValue(style_.padding[YGEdgeStart], widthSize); if (YGFlexDirectionIsRow(axis) && style_.padding[YGEdgeStart].unit != YGUnitUndefined && - !paddingEdgeStart.isUndefined() && paddingEdgeStart.getValue() >= 0.0f) { + !paddingEdgeStart.isUndefined() && paddingEdgeStart.unwrap() >= 0.0f) { return paddingEdgeStart; } @@ -471,7 +471,7 @@ YGFloatOptional YGNode::getTrailingPadding( if (YGFlexDirectionIsRow(axis) && style_.padding[YGEdgeEnd].unit != YGUnitUndefined && !YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() && - YGResolveValue(style_.padding[YGEdgeEnd], widthSize).getValue() >= 0.0f) { + YGResolveValue(style_.padding[YGEdgeEnd], widthSize).unwrap() >= 0.0f) { return YGResolveValue(style_.padding[YGEdgeEnd], widthSize); } diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 541a6fef..8eb33f93 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -43,7 +43,7 @@ static void appendFloatOptionalIfDefined( const string key, const YGFloatOptional num) { if (!num.isUndefined()) { - appendFormatedString(base, "%s: %g; ", key.c_str(), num.getValue()); + appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap()); } } diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp index bc90463e..78df8b01 100644 --- a/yoga/YGStyle.cpp +++ b/yoga/YGStyle.cpp @@ -28,26 +28,26 @@ bool YGStyle::operator==(const YGStyle& style) { if (areNonFloatValuesEqual && !flex.isUndefined() && !style.flex.isUndefined()) { areNonFloatValuesEqual = - areNonFloatValuesEqual && flex.getValue() == style.flex.getValue(); + areNonFloatValuesEqual && flex == style.flex; } areNonFloatValuesEqual = areNonFloatValuesEqual && flexGrow.isUndefined() == style.flexGrow.isUndefined(); if (areNonFloatValuesEqual && !flexGrow.isUndefined()) { areNonFloatValuesEqual = areNonFloatValuesEqual && - flexGrow.getValue() == style.flexGrow.getValue(); + flexGrow == style.flexGrow; } areNonFloatValuesEqual = areNonFloatValuesEqual && flexShrink.isUndefined() == style.flexShrink.isUndefined(); if (areNonFloatValuesEqual && !style.flexShrink.isUndefined()) { areNonFloatValuesEqual = areNonFloatValuesEqual && - flexShrink.getValue() == style.flexShrink.getValue(); + flexShrink == style.flexShrink; } if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) { areNonFloatValuesEqual = areNonFloatValuesEqual && - aspectRatio.getValue() == style.aspectRatio.getValue(); + aspectRatio == style.aspectRatio; } return areNonFloatValuesEqual; diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 8db18e9e..abc4ae74 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -581,14 +581,14 @@ void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode) { float YGNodeStyleGetFlexGrow(const YGNodeRef node) { return node->getStyle().flexGrow.isUndefined() ? kDefaultFlexGrow - : node->getStyle().flexGrow.getValue(); + : node->getStyle().flexGrow.unwrap(); } float YGNodeStyleGetFlexShrink(const YGNodeRef node) { return node->getStyle().flexShrink.isUndefined() ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink : kDefaultFlexShrink) - : node->getStyle().flexShrink.getValue(); + : node->getStyle().flexShrink.unwrap(); } namespace { @@ -857,7 +857,7 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { // TODO(T26792433): Change the API to accept YGFloatOptional. float YGNodeStyleGetFlex(const YGNodeRef node) { return node->getStyle().flex.isUndefined() ? YGUndefined - : node->getStyle().flex.getValue(); + : node->getStyle().flex.unwrap(); } // TODO(T26792433): Change the API to accept YGFloatOptional. @@ -959,7 +959,7 @@ float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) { // TODO(T26792433): Change the API to accept YGFloatOptional. float YGNodeStyleGetAspectRatio(const YGNodeRef node) { const YGFloatOptional op = node->getStyle().aspectRatio; - return op.isUndefined() ? YGUndefined : op.getValue(); + return op.isUndefined() ? YGUndefined : op.unwrap(); } // TODO(T26792433): Change the API to accept YGFloatOptional. @@ -1229,11 +1229,11 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( node->getStyle().maxDimensions[YGDimensionWidth], axisSize); } - if (!max.isUndefined() && max.getValue() >= 0 && value > max.getValue()) { + if (!max.isUndefined() && max.unwrap() >= 0 && value > max.unwrap()) { return max; } - if (!min.isUndefined() && min.getValue() >= 0 && value < min.getValue()) { + if (!min.isUndefined() && min.unwrap() >= 0 && value < min.unwrap()) { return min; } @@ -1277,14 +1277,14 @@ static void YGConstrainMaxSizeForMode( switch (*mode) { case YGMeasureModeExactly: case YGMeasureModeAtMost: - *size = (maxSize.isUndefined() || *size < maxSize.getValue()) + *size = (maxSize.isUndefined() || *size < maxSize.unwrap()) ? *size - : maxSize.getValue(); + : maxSize.unwrap(); break; case YGMeasureModeUndefined: if (!maxSize.isUndefined()) { *mode = YGMeasureModeAtMost; - *size = maxSize.getValue(); + *size = maxSize.unwrap(); } break; } @@ -1399,13 +1399,13 @@ static void YGNodeComputeFlexBasisForChild( if (!child->getStyle().aspectRatio.isUndefined()) { if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { childHeight = marginColumn + - (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + (childWidth - marginRow) / child->getStyle().aspectRatio.unwrap(); childHeightMeasureMode = YGMeasureModeExactly; } else if ( isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { childWidth = marginRow + (childHeight - marginColumn) * - child->getStyle().aspectRatio.getValue(); + child->getStyle().aspectRatio.unwrap(); childWidthMeasureMode = YGMeasureModeExactly; } } @@ -1425,7 +1425,7 @@ static void YGNodeComputeFlexBasisForChild( childWidthMeasureMode = YGMeasureModeExactly; if (!child->getStyle().aspectRatio.isUndefined()) { childHeight = - (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + (childWidth - marginRow) / child->getStyle().aspectRatio.unwrap(); childHeightMeasureMode = YGMeasureModeExactly; } } @@ -1442,7 +1442,7 @@ static void YGNodeComputeFlexBasisForChild( if (!child->getStyle().aspectRatio.isUndefined()) { childWidth = (childHeight - marginColumn) * - child->getStyle().aspectRatio.getValue(); + child->getStyle().aspectRatio.unwrap(); childWidthMeasureMode = YGMeasureModeExactly; } } @@ -1557,10 +1557,10 @@ static void YGNodeAbsoluteLayoutChild( if (YGFloatIsUndefined(childWidth)) { childWidth = marginRow + (childHeight - marginColumn) * - child->getStyle().aspectRatio.getValue(); + child->getStyle().aspectRatio.unwrap(); } else if (YGFloatIsUndefined(childHeight)) { childHeight = marginColumn + - (childWidth - marginRow) / child->getStyle().aspectRatio.getValue(); + (childWidth - marginRow) / child->getStyle().aspectRatio.unwrap(); } } } @@ -1886,14 +1886,14 @@ static float YGNodeCalculateAvailableInnerDim( YGResolveValue(node->getStyle().minDimensions[dimension], ownerDim); const float minInnerDim = minDimensionOptional.isUndefined() ? 0.0f - : minDimensionOptional.getValue() - paddingAndBorder; + : minDimensionOptional.unwrap() - paddingAndBorder; const YGFloatOptional maxDimensionOptional = YGResolveValue(node->getStyle().maxDimensions[dimension], ownerDim); const float maxInnerDim = maxDimensionOptional.isUndefined() ? FLT_MAX - : maxDimensionOptional.getValue() - paddingAndBorder; + : maxDimensionOptional.unwrap() - paddingAndBorder; availableInnerDim = YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim); } @@ -2166,9 +2166,9 @@ static float YGDistributeFreeSpaceSecondPass( if (!currentRelativeChild->getStyle().aspectRatio.isUndefined()) { childCrossSize = isMainAxisRow ? (childMainSize - marginMain) / - currentRelativeChild->getStyle().aspectRatio.getValue() + currentRelativeChild->getStyle().aspectRatio.unwrap() : (childMainSize - marginMain) * - currentRelativeChild->getStyle().aspectRatio.getValue(); + currentRelativeChild->getStyle().aspectRatio.unwrap(); childCrossMeasureMode = YGMeasureModeExactly; childCrossSize += marginCross; @@ -3135,9 +3135,9 @@ static void YGNodelayoutImpl( ? child->getMarginForAxis(crossAxis, availableInnerWidth) .unwrap() + (isMainAxisRow ? childMainSize / - child->getStyle().aspectRatio.getValue() + child->getStyle().aspectRatio.unwrap() : childMainSize * - child->getStyle().aspectRatio.getValue()) + child->getStyle().aspectRatio.unwrap()) : collectedFlexItemsValues.crossDim; childMainSize += -- 2.50.1.windows.1 From 236bcc1a39421d66cc5b4a8bef6d428873820f71 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:30 -0800 Subject: [PATCH 34/53] Pass `YGFloatOptional` by value, not reference Summary: @public `YGFloatOptional` is a 32bit type now, and can be passed by value efficiently. Reviewed By: SidharthGuglani Differential Revision: D13439603 fbshipit-source-id: e12539ad5b3cccbd5bc27869866ca66c023b24a7 --- yoga/YGNode.cpp | 13 ++++++------- yoga/YGNode.h | 2 +- yoga/Yoga.cpp | 6 +++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 3da72cb6..1a08fab8 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -175,7 +175,7 @@ void YGNode::setLayoutLastOwnerDirection(YGDirection direction) { } void YGNode::setLayoutComputedFlexBasis( - const YGFloatOptional& computedFlexBasis) { + const YGFloatOptional computedFlexBasis) { layout_.computedFlexBasis = computedFlexBasis; } @@ -451,7 +451,7 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const { YGFloatOptional YGNode::getLeadingPadding( const YGFlexDirection axis, const float widthSize) const { - const YGFloatOptional& paddingEdgeStart = + const YGFloatOptional paddingEdgeStart = YGResolveValue(style_.padding[YGEdgeStart], widthSize); if (YGFlexDirectionIsRow(axis) && style_.padding[YGEdgeStart].unit != YGUnitUndefined && @@ -468,11 +468,10 @@ YGFloatOptional YGNode::getLeadingPadding( YGFloatOptional YGNode::getTrailingPadding( const YGFlexDirection axis, const float widthSize) const { - if (YGFlexDirectionIsRow(axis) && - style_.padding[YGEdgeEnd].unit != YGUnitUndefined && - !YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() && - YGResolveValue(style_.padding[YGEdgeEnd], widthSize).unwrap() >= 0.0f) { - return YGResolveValue(style_.padding[YGEdgeEnd], widthSize); + const YGFloatOptional paddingEdgeEnd = + YGResolveValue(style_.padding[YGEdgeEnd], widthSize); + if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) { + return paddingEdgeEnd; } YGFloatOptional resolvedValue = YGResolveValue( diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 719eb2ea..57312812 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -235,7 +235,7 @@ struct YGNode { void setDirty(bool isDirty); void setLayoutLastOwnerDirection(YGDirection direction); - void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis); + void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis); void setLayoutComputedFlexBasisGeneration( uint32_t computedFlexBasisGeneration); void setLayoutMeasuredDimension(float measuredDimension, int index); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index abc4ae74..653f47e7 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1325,14 +1325,14 @@ static void YGNodeComputeFlexBasisForChild( child->getConfig(), YGExperimentalFeatureWebFlexBasis) && child->getLayout().computedFlexBasisGeneration != gCurrentGenerationCount)) { - const YGFloatOptional& paddingAndBorder = YGFloatOptional( + const YGFloatOptional paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); child->setLayoutComputedFlexBasis( YGFloatOptionalMax(resolvedFlexBasis, paddingAndBorder)); } } else if (isMainAxisRow && isRowStyleDimDefined) { // The width is definite, so use that as the flex basis. - const YGFloatOptional& paddingAndBorder = YGFloatOptional( + const YGFloatOptional paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( @@ -1341,7 +1341,7 @@ static void YGNodeComputeFlexBasisForChild( paddingAndBorder)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { // The height is definite, so use that as the flex basis. - const YGFloatOptional& paddingAndBorder = + const YGFloatOptional paddingAndBorder = YGFloatOptional(YGNodePaddingAndBorderForAxis( child, YGFlexDirectionColumn, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( -- 2.50.1.windows.1 From 96d93f29826257ff6e9bb6c19211adb423029c29 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:31 -0800 Subject: [PATCH 35/53] Inline `YGFloatOptional` completely Summary: @public `YGFLoatOptional` only contains trivial functionality. Make it header-only. Reviewed By: SidharthGuglani Differential Revision: D13439609 fbshipit-source-id: 3f3c6c3a15e05ac55da2af30eb629f786ecb90a9 --- yoga/YGFloatOptional.cpp | 49 ---------------------------------------- yoga/YGFloatOptional.h | 39 ++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 59 deletions(-) delete mode 100644 yoga/YGFloatOptional.cpp diff --git a/yoga/YGFloatOptional.cpp b/yoga/YGFloatOptional.cpp deleted file mode 100644 index d202d4d5..00000000 --- a/yoga/YGFloatOptional.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. - */ -#include "YGFloatOptional.h" -#include -#include -#include "Yoga-internal.h" -#include "Yoga.h" - -using namespace facebook; - -bool YGFloatOptional::operator==(YGFloatOptional op) const { - return value_ == op.value_ || (isUndefined() && op.isUndefined()); -} - -bool YGFloatOptional::operator!=(YGFloatOptional op) const { - return !(*this == op); -} - -bool YGFloatOptional::operator==(float val) const { - return value_ == val || (isUndefined() && yoga::isUndefined(val)); -} - -bool YGFloatOptional::operator!=(float val) const { - return !(*this == val); -} - -YGFloatOptional YGFloatOptional::operator+(YGFloatOptional op) const { - return YGFloatOptional{value_ + op.value_}; -} - -bool YGFloatOptional::operator>(YGFloatOptional op) const { - return value_ > op.value_; -} - -bool YGFloatOptional::operator<(YGFloatOptional op) const { - return value_ < op.value_; -} - -bool YGFloatOptional::operator>=(YGFloatOptional op) const { - return *this > op || *this == op; -} - -bool YGFloatOptional::operator<=(YGFloatOptional op) const { - return *this < op || *this == op; -} diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h index b4974798..44cf344e 100644 --- a/yoga/YGFloatOptional.h +++ b/yoga/YGFloatOptional.h @@ -8,6 +8,7 @@ #include #include +#include "Yoga-internal.h" struct YGFloatOptional { private: @@ -18,7 +19,7 @@ struct YGFloatOptional { constexpr YGFloatOptional() = default; // returns the wrapped value, or a value x with YGIsUndefined(x) == true - float unwrap() const { + constexpr float unwrap() const { return value_; } @@ -26,14 +27,32 @@ struct YGFloatOptional { return std::isnan(value_); } - YGFloatOptional operator+(YGFloatOptional op) const; - bool operator>(YGFloatOptional op) const; - bool operator<(YGFloatOptional op) const; - bool operator>=(YGFloatOptional op) const; - bool operator<=(YGFloatOptional op) const; - bool operator==(YGFloatOptional op) const; - bool operator!=(YGFloatOptional op) const; + YGFloatOptional operator+(YGFloatOptional op) const { + return YGFloatOptional{value_ + op.value_}; + } + bool operator>(YGFloatOptional op) const { + return value_ > op.value_; + } + bool operator<(YGFloatOptional op) const { + return value_ < op.value_; + } + bool operator>=(YGFloatOptional op) const { + return *this > op || *this == op; + } + bool operator<=(YGFloatOptional op) const { + return *this < op || *this == op; + } + bool operator==(YGFloatOptional op) const { + return value_ == op.value_ || (isUndefined() && op.isUndefined()); + } + bool operator!=(YGFloatOptional op) const { + return !(*this == op); + } - bool operator==(float val) const; - bool operator!=(float val) const; + bool operator==(float val) const { + return value_ == val || (isUndefined() && yoga::isUndefined(val)); + } + bool operator!=(float val) const { + return !(*this == val); + } }; -- 2.50.1.windows.1 From 3f794397185359cb111f6e4a664db123071b6b92 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:31 -0800 Subject: [PATCH 36/53] Get rid of `static_cast` in `YGResolveValue` Summary: @public Removes `static_cast` from `YGResolveValue` Reviewed By: SidharthGuglani Differential Revision: D13439605 fbshipit-source-id: 8736541c8e1d43fd698d368cb4f3211ffd929364 --- yoga/Utils.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/yoga/Utils.h b/yoga/Utils.h index 9ea7a738..fed3c1fb 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -95,16 +95,13 @@ inline YGFloatOptional YGResolveValue( const YGValue value, const float ownerSize) { switch (value.unit) { - case YGUnitUndefined: - case YGUnitAuto: - return YGFloatOptional(); case YGUnitPoint: - return YGFloatOptional(value.value); + return YGFloatOptional{value.value}; case YGUnitPercent: - return YGFloatOptional( - static_cast(value.value * ownerSize * 0.01)); + return YGFloatOptional{value.value * ownerSize * 0.01f}; + default: + return YGFloatOptional{}; } - return YGFloatOptional(); } inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { -- 2.50.1.windows.1 From 852db1d885943324db7eb50ddc6c6df124a60e6c Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:31 -0800 Subject: [PATCH 37/53] Remove unnecessary `static` keyword MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: @public Header-declared inline functions shouldn’t be decleared `static` Reviewed By: SidharthGuglani Differential Revision: D13439607 fbshipit-source-id: 89555bb19a3fff6e29ca4afc10fe15fecca8fa17 --- yoga/Utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yoga/Utils.h b/yoga/Utils.h index fed3c1fb..a0d49235 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -123,7 +123,7 @@ inline YGFlexDirection YGResolveFlexDirection( return flexDirection; } -static inline YGFloatOptional YGResolveValueMargin( +inline YGFloatOptional YGResolveValueMargin( const YGValue value, const float ownerSize) { return value.unit == YGUnitAuto ? YGFloatOptional(0) -- 2.50.1.windows.1 From e96d14395c0af54579a38926a44bbf07a97359fb Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:31 -0800 Subject: [PATCH 38/53] `YGNodeBoundAxisWithinMinAndMax` accepts `YGFloatOptional` Summary: @public Saves some calls to `.unwrap()` Reviewed By: SidharthGuglani Differential Revision: D13439600 fbshipit-source-id: ce0f6bad9a0709e9d64e23d8349bc2423b9b2ad4 --- yoga/Yoga.cpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 653f47e7..bc457b1f 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1212,7 +1212,7 @@ static inline bool YGNodeIsLayoutDimDefined( static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( const YGNodeRef node, const YGFlexDirection axis, - const float value, + const YGFloatOptional value, const float axisSize) { YGFloatOptional min; YGFloatOptional max; @@ -1229,15 +1229,15 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( node->getStyle().maxDimensions[YGDimensionWidth], axisSize); } - if (!max.isUndefined() && max.unwrap() >= 0 && value > max.unwrap()) { + if (max >= YGFloatOptional{0} && value > max) { return max; } - if (!min.isUndefined() && min.unwrap() >= 0 && value < min.unwrap()) { + if (min >= YGFloatOptional{0} && value < min) { return min; } - return YGFloatOptional(value); + return value; } // Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't @@ -1249,7 +1249,9 @@ static inline float YGNodeBoundAxis( const float axisSize, const float widthSize) { return YGFloatMax( - YGNodeBoundAxisWithinMinAndMax(node, axis, value, axisSize).unwrap(), + YGNodeBoundAxisWithinMinAndMax( + node, axis, YGFloatOptional{value}, axisSize) + .unwrap(), YGNodePaddingAndBorderForAxis(node, axis, widthSize)); } @@ -2021,7 +2023,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( YGNodeBoundAxisWithinMinAndMax( child, mainAxis, - child->getLayout().computedFlexBasis.unwrap(), + child->getLayout().computedFlexBasis, mainAxisownerSize) .unwrap(); @@ -2096,13 +2098,12 @@ static float YGDistributeFreeSpaceSecondPass( const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - childFlexBasis = - YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - currentRelativeChild->getLayout().computedFlexBasis.unwrap(), - mainAxisownerSize) - .unwrap(); + childFlexBasis = YGNodeBoundAxisWithinMinAndMax( + currentRelativeChild, + mainAxis, + currentRelativeChild->getLayout().computedFlexBasis, + mainAxisownerSize) + .unwrap(); float updatedMainSize = childFlexBasis; if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && @@ -2280,7 +2281,7 @@ static void YGDistributeFreeSpaceFirstPass( YGNodeBoundAxisWithinMinAndMax( currentRelativeChild, mainAxis, - currentRelativeChild->getLayout().computedFlexBasis.unwrap(), + currentRelativeChild->getLayout().computedFlexBasis, mainAxisownerSize) .unwrap(); @@ -3458,7 +3459,10 @@ static void YGNodelayoutImpl( YGFloatMin( availableInnerMainDim + paddingAndBorderAxisMain, YGNodeBoundAxisWithinMinAndMax( - node, mainAxis, maxLineMainDim, mainAxisownerSize) + node, + mainAxis, + YGFloatOptional{maxLineMainDim}, + mainAxisownerSize) .unwrap()), paddingAndBorderAxisMain), dim[mainAxis]); @@ -3488,7 +3492,8 @@ static void YGNodelayoutImpl( YGNodeBoundAxisWithinMinAndMax( node, crossAxis, - totalLineCrossDim + paddingAndBorderAxisCross, + YGFloatOptional{totalLineCrossDim + + paddingAndBorderAxisCross}, crossAxisownerSize) .unwrap()), paddingAndBorderAxisCross), -- 2.50.1.windows.1 From 4f51871fa8f2bd5f8b47000bfd769e74b8225f7e Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:31 -0800 Subject: [PATCH 39/53] Remove templates for setting/getting style properties Summary: @public Replaces the `StyleProp` template with a simple setter macro / inlined getter code. The template was introduced to replace more extensive macros that would generate function signatures, too. Here, we keep the spirit of that change by only generating function bodies. Reviewed By: SidharthGuglani Differential Revision: D13439612 fbshipit-source-id: 36f6a86917d035be6891cb736d1f288d8e02f5cf --- yoga/Yoga.cpp | 63 ++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index bc457b1f..3356a811 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -593,19 +593,6 @@ float YGNodeStyleGetFlexShrink(const YGNodeRef node) { namespace { -template -struct StyleProp { - static T get(YGNodeRef node) { - return node->getStyle().*P; - } - static void set(YGNodeRef node, T newValue) { - if (node->getStyle().*P != newValue) { - node->getStyle().*P = newValue; - node->markDirtyAndPropogate(); - } - } -}; - struct Value { template static YGValue create(float value) { @@ -765,84 +752,88 @@ struct DimensionProp { return node->getLayout().instanceName[edge]; \ } -void YGNodeStyleSetDirection( - const YGNodeRef node, - const YGDirection direction) { - StyleProp::set(node, direction); +#define YG_NODE_STYLE_SET(node, property, value) \ + if (node->getStyle().property != value) { \ + node->getStyle().property = value; \ + node->markDirtyAndPropogate(); \ + } + +void YGNodeStyleSetDirection(const YGNodeRef node, const YGDirection value) { + YG_NODE_STYLE_SET(node, direction, value); } YGDirection YGNodeStyleGetDirection(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().direction; } void YGNodeStyleSetFlexDirection( const YGNodeRef node, const YGFlexDirection flexDirection) { - StyleProp::set(node, flexDirection); + YG_NODE_STYLE_SET(node, flexDirection, flexDirection); } YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().flexDirection; } void YGNodeStyleSetJustifyContent( const YGNodeRef node, const YGJustify justifyContent) { - StyleProp::set(node, justifyContent); + YG_NODE_STYLE_SET(node, justifyContent, justifyContent); } YGJustify YGNodeStyleGetJustifyContent(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().justifyContent; } void YGNodeStyleSetAlignContent( const YGNodeRef node, const YGAlign alignContent) { - StyleProp::set(node, alignContent); + YG_NODE_STYLE_SET(node, alignContent, alignContent); } YGAlign YGNodeStyleGetAlignContent(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().alignContent; } void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) { - StyleProp::set(node, alignItems); + YG_NODE_STYLE_SET(node, alignItems, alignItems); } YGAlign YGNodeStyleGetAlignItems(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().alignItems; } void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) { - StyleProp::set(node, alignSelf); + YG_NODE_STYLE_SET(node, alignSelf, alignSelf); } YGAlign YGNodeStyleGetAlignSelf(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().alignSelf; } void YGNodeStyleSetPositionType( const YGNodeRef node, const YGPositionType positionType) { - StyleProp::set(node, positionType); + YG_NODE_STYLE_SET(node, positionType, positionType); } YGPositionType YGNodeStyleGetPositionType(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().positionType; } void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) { - StyleProp::set(node, flexWrap); + YG_NODE_STYLE_SET(node, flexWrap, flexWrap); } YGWrap YGNodeStyleGetFlexWrap(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().flexWrap; } void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) { - StyleProp::set(node, overflow); + YG_NODE_STYLE_SET(node, overflow, overflow); } YGOverflow YGNodeStyleGetOverflow(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().overflow; } void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) { - StyleProp::set(node, display); + YG_NODE_STYLE_SET(node, display, display); } YGDisplay YGNodeStyleGetDisplay(const YGNodeRef node) { - return StyleProp::get(node); + return node->getStyle().display; } // TODO(T26792433): Change the API to accept YGFloatOptional. -- 2.50.1.windows.1 From dd97fcc96825d0eb7e3fdd1ffb20b150c049bdf0 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:31 -0800 Subject: [PATCH 40/53] Use bitfields for enum members of `YGStyle` Summary: @public Puts all enum fields of `YGStyle` into bitfields. This saves 36 bytes (> 3%) per node. Reviewed By: SidharthGuglani Differential Revision: D13439606 fbshipit-source-id: b60a5444762041bc6f8cc5e04757034cb6893b30 --- yoga/YGStyle.h | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index c3a01d44..c4f7e3c7 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -30,16 +30,16 @@ constexpr std::array kYGDefaultDimensionValuesUnit = { struct YGStyle { using Dimensions = std::array; - YGDirection direction = YGDirectionInherit; - YGFlexDirection flexDirection = YGFlexDirectionColumn; - YGJustify justifyContent = YGJustifyFlexStart; - YGAlign alignContent = YGAlignFlexStart; - YGAlign alignItems = YGAlignStretch; - YGAlign alignSelf = YGAlignAuto; - YGPositionType positionType = YGPositionTypeRelative; - YGWrap flexWrap = YGWrapNoWrap; - YGOverflow overflow = YGOverflowVisible; - YGDisplay display = YGDisplayFlex; + YGDirection direction : 2; + YGFlexDirection flexDirection : 2; + YGJustify justifyContent : 3; + YGAlign alignContent : 3; + YGAlign alignItems : 3; + YGAlign alignSelf : 3; + YGPositionType positionType : 1; + YGWrap flexWrap : 2; + YGOverflow overflow : 2; + YGDisplay display : 1; YGFloatOptional flex = {}; YGFloatOptional flexGrow = {}; YGFloatOptional flexShrink = {}; @@ -54,7 +54,17 @@ struct YGStyle { // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio = {}; - YGStyle() = default; + YGStyle() + : direction(YGDirectionInherit), + flexDirection(YGFlexDirectionColumn), + justifyContent(YGJustifyFlexStart), + alignContent(YGAlignFlexStart), + alignItems(YGAlignStretch), + alignSelf(YGAlignAuto), + positionType(YGPositionTypeRelative), + flexWrap(YGWrapNoWrap), + overflow(YGOverflowVisible), + display(YGDisplayFlex) {} bool operator==(const YGStyle& style); bool operator!=(YGStyle style) { -- 2.50.1.windows.1 From 130a9a2aa201938ed7aaa56319e861cc0f6648c5 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 07:09:31 -0800 Subject: [PATCH 41/53] Don't pass `std::string` by pointer Summary: @public Pass strings by mutable ref rather than pointer. Reviewed By: SidharthGuglani Differential Revision: D13439613 fbshipit-source-id: ea889abe0fe8ec44ae02f13c1d9a10c0dbfdbcf1 --- yoga/YGNodePrint.cpp | 27 +++++++++++++-------------- yoga/YGNodePrint.h | 2 +- yoga/Yoga.cpp | 2 +- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 8eb33f93..753a00b6 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -14,9 +14,9 @@ namespace facebook { namespace yoga { typedef std::string string; -static void indent(string* base, uint32_t level) { +static void indent(string& base, uint32_t level) { for (uint32_t i = 0; i < level; ++i) { - base->append(" "); + base.append(" "); } } @@ -25,7 +25,7 @@ static bool areFourValuesEqual(const std::array& four) { YGValueEqual(four[0], four[3]); } -static void appendFormatedString(string* str, const char* fmt, ...) { +static void appendFormatedString(string& str, const char* fmt, ...) { va_list args; va_start(args, fmt); va_list argsCopy; @@ -35,11 +35,11 @@ static void appendFormatedString(string* str, const char* fmt, ...) { vsnprintf(buf.data(), buf.size(), fmt, argsCopy); va_end(argsCopy); string result = string(buf.begin(), buf.end() - 1); - str->append(result); + str.append(result); } static void appendFloatOptionalIfDefined( - string* base, + string& base, const string key, const YGFloatOptional num) { if (!num.isUndefined()) { @@ -48,12 +48,12 @@ static void appendFloatOptionalIfDefined( } static void appendNumberIfNotUndefined( - string* base, + string& base, const string key, const YGValue number) { if (number.unit != YGUnitUndefined) { if (number.unit == YGUnitAuto) { - base->append(key + ": auto; "); + base.append(key + ": auto; "); } else { string unit = number.unit == YGUnitPoint ? "px" : "%%"; appendFormatedString( @@ -63,24 +63,23 @@ static void appendNumberIfNotUndefined( } static void -appendNumberIfNotAuto(string* base, const string& key, const YGValue number) { +appendNumberIfNotAuto(string& base, const string& key, const YGValue number) { if (number.unit != YGUnitAuto) { appendNumberIfNotUndefined(base, key, number); } } static void -appendNumberIfNotZero(string* base, const string& str, const YGValue number) { - +appendNumberIfNotZero(string& base, const string& str, const YGValue number) { if (number.unit == YGUnitAuto) { - base->append(str + ": auto; "); + base.append(str + ": auto; "); } else if (!YGFloatsEqual(number.value, 0)) { appendNumberIfNotUndefined(base, str, number); } } static void appendEdges( - string* base, + string& base, const string& key, const std::array& edges) { if (areFourValuesEqual(edges)) { @@ -94,7 +93,7 @@ static void appendEdges( } static void appendEdgeIfNotUndefined( - string* base, + string& base, const string& str, const std::array& edges, const YGEdge edge) { @@ -103,7 +102,7 @@ static void appendEdgeIfNotUndefined( } void YGNodeToString( - std::string* str, + std::string& str, YGNodeRef node, YGPrintOptions options, uint32_t level) { diff --git a/yoga/YGNodePrint.h b/yoga/YGNodePrint.h index 9d36ba8d..9615bf8e 100644 --- a/yoga/YGNodePrint.h +++ b/yoga/YGNodePrint.h @@ -13,7 +13,7 @@ namespace facebook { namespace yoga { void YGNodeToString( - std::string* str, + std::string& str, YGNodeRef node, YGPrintOptions options, uint32_t level); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 3356a811..4a1a98a2 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1060,7 +1060,7 @@ static void YGNodePrintInternal( const YGNodeRef node, const YGPrintOptions options) { std::string str; - facebook::yoga::YGNodeToString(&str, node, options, 0); + facebook::yoga::YGNodeToString(str, node, options, 0); YGLog(node, YGLogLevelDebug, str.c_str()); } -- 2.50.1.windows.1 From c5f24440489aaad73f3d3fa4f50a6eed07de95f7 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Thu, 13 Dec 2018 10:38:10 -0800 Subject: [PATCH 42/53] Don't use `default` in exhaustive switch Summary: @public removes the `default` case from an already exhaustive switch. Reviewed By: SidharthGuglani Differential Revision: D13451869 fbshipit-source-id: 32727330c7fce013963f5c83c95a73b230d5c938 --- yoga/YGValue.h | 1 - 1 file changed, 1 deletion(-) diff --git a/yoga/YGValue.h b/yoga/YGValue.h index 4e43f7b2..59440be3 100644 --- a/yoga/YGValue.h +++ b/yoga/YGValue.h @@ -44,7 +44,6 @@ inline bool operator==(const YGValue& lhs, const YGValue& rhs) { return true; case YGUnitPoint: case YGUnitPercent: - default: return lhs.value == rhs.value; } } -- 2.50.1.windows.1 From 8bc89651d6a7e71258f1b6e265b751e55d967548 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 14 Dec 2018 09:20:27 -0800 Subject: [PATCH 43/53] Introduce `CompactValue` Summary: @public `CompactValue` represents a `YGValue` in 32bits instead of 64. This comes at the cost of a range limitation, as one exponent bit is borrowed for the unit. *Undefined* and *Auto* have no magnitude, and are represented as *NaN* values. The data structure is meant to be used as a field type on `YGStyle` to save memory. This is header-only for efficient inlining. Reviewed By: jackerghan, aCorrado Differential Revision: D13187211 fbshipit-source-id: 16e3ffad592e38e2493e4f7c8b952d372e449846 --- BUCK | 2 + tests/CompactValueTest.cpp | 349 +++++++++++++++++++++++++++++++++++++ yoga/CompactValue.h | 182 +++++++++++++++++++ 3 files changed, 533 insertions(+) create mode 100644 tests/CompactValueTest.cpp create mode 100644 yoga/CompactValue.h diff --git a/BUCK b/BUCK index aeeac450..4087a183 100644 --- a/BUCK +++ b/BUCK @@ -20,6 +20,7 @@ TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + [ yoga_cxx_library( name = "yoga", srcs = glob(["yoga/*.cpp"]), + headers = subdir_glob([("", "yoga/**/*.h")]), header_namespace = "", exported_headers = subdir_glob([("", "yoga/*.h")]), compiler_flags = COMPILER_FLAGS, @@ -34,6 +35,7 @@ yoga_cxx_library( yoga_cxx_test( name = "YogaTests", srcs = glob(["tests/*.cpp"]), + headers = subdir_glob([("", "yoga/**/*.h")]), compiler_flags = TEST_COMPILER_FLAGS, contacts = ["emilsj@fb.com"], visibility = ["PUBLIC"], diff --git a/tests/CompactValueTest.cpp b/tests/CompactValueTest.cpp new file mode 100644 index 00000000..7d2afc13 --- /dev/null +++ b/tests/CompactValueTest.cpp @@ -0,0 +1,349 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + */ +#define YOGA_COMPACT_VALUE_TEST + +#include +#include +#include + +using facebook::yoga::detail::CompactValue; + +const auto tooSmall = nextafterf(CompactValue::LOWER_BOUND, -INFINITY); +const auto tooLargePoints = + nextafterf(CompactValue::UPPER_BOUND_POINT, INFINITY); +const auto tooLargePercent = + nextafterf(CompactValue::UPPER_BOUND_PERCENT, INFINITY); + +TEST(YogaTest, compact_value_can_represent_undefined) { + auto c = CompactValue{YGValue{12.5f, YGUnitUndefined}}; + YGValue v = c; + ASSERT_EQ(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{-1.25, YGUnitPoint})); + ASSERT_NE(v, (YGValue{25, YGUnitPercent})); + ASSERT_TRUE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_auto) { + auto c = CompactValue{YGValue{0, YGUnitAuto}}; + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_EQ(v, YGValueAuto); + ASSERT_NE(v, (YGValue{-1.25, YGUnitPoint})); + ASSERT_NE(v, (YGValue{25, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_TRUE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_zero_points) { + auto c = CompactValue{YGValue{0, YGUnitPoint}}; + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{0, YGUnitPoint})); + ASSERT_NE(v, (YGValue{0, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_lower_bound_points) { + auto c = CompactValue({YGValue{CompactValue::LOWER_BOUND, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPoint})); + ASSERT_NE(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_negative_lower_bound_points) { + auto c = CompactValue({YGValue{-CompactValue::LOWER_BOUND, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPoint})); + ASSERT_NE(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_clamps_smaller_than_lower_bound_points_to_zero) { + auto c = CompactValue({YGValue{tooSmall, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{0, YGUnitPoint})); + ASSERT_NE(v, (YGValue{0, YGUnitPercent})); +} + +TEST( + YogaTest, + compact_value_clamps_greater_than_negative_lower_bound_points_to_zero) { + auto c = CompactValue({YGValue{-tooSmall, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{0, YGUnitPoint})); + ASSERT_NE(v, (YGValue{0, YGUnitPercent})); +} + +TEST(YogaTest, compact_value_can_represent_upper_bound_points) { + auto c = + CompactValue({YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); + ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_negative_upper_bound_points) { + auto c = + CompactValue({YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); + ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST( + YogaTest, + compact_value_clamps_greater_than__upper_bound_points_to_upper_bound) { + auto c = CompactValue({YGValue{tooLargePoints, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); + ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); +} + +TEST( + YogaTest, + compact_value_clamps_smaller_than_negative_upper_bound_points_to_upper_bound) { + auto c = CompactValue({YGValue{-tooLargePoints, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); + ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); +} + +TEST(YogaTest, compact_value_can_represent_one_point) { + auto c = CompactValue({YGValue{1, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{1, YGUnitPoint})); + ASSERT_NE(v, (YGValue{1, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_negative_one_point) { + auto c = CompactValue({YGValue{-1, YGUnitPoint}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_EQ(v, (YGValue{-1, YGUnitPoint})); + ASSERT_NE(v, (YGValue{-1, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_zero_percent) { + auto c = CompactValue{YGValue{0, YGUnitPercent}}; + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{0, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{0, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_lower_bound_percent) { + auto c = CompactValue({YGValue{CompactValue::LOWER_BOUND, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_negative_lower_bound_percent) { + auto c = CompactValue({YGValue{-CompactValue::LOWER_BOUND, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_clamps_smaller_than_lower_bound_percent_to_zero) { + auto c = CompactValue({YGValue{tooSmall, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{0, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{0, YGUnitPercent})); +} + +TEST( + YogaTest, + compact_value_clamps_greater_than_negative_lower_bound_percent_to_zero) { + auto c = CompactValue({YGValue{-tooSmall, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{0, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{0, YGUnitPercent})); +} + +TEST(YogaTest, compact_value_can_represent_upper_bound_percent) { + auto c = + CompactValue({YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_negative_upper_bound_percent) { + auto c = CompactValue( + {YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST( + YogaTest, + compact_value_clamps_greater_than_upper_bound_percent_to_upper_bound) { + auto c = CompactValue({YGValue{tooLargePercent, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); +} + +TEST( + YogaTest, + compact_value_clamps_smaller_than_negative_upper_bound_percent_to_upper_bound) { + auto c = CompactValue({YGValue{-tooLargePercent, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); +} + +TEST(YogaTest, compact_value_can_represent_one_percent) { + auto c = CompactValue({YGValue{1, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{1, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{1, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, compact_value_can_represent_negative_one_percent) { + auto c = CompactValue({YGValue{-1, YGUnitPercent}}); + YGValue v = c; + ASSERT_NE(v, YGValueUndefined); + ASSERT_NE(v, YGValueAuto); + ASSERT_NE(v, (YGValue{-1, YGUnitPoint})); + ASSERT_EQ(v, (YGValue{-1, YGUnitPercent})); + ASSERT_FALSE(c.isUndefined()); + ASSERT_FALSE(c.isAuto()); +} + +TEST(YogaTest, dedicated_unit_factories) { + ASSERT_EQ(CompactValue::ofUndefined(), CompactValue(YGValueUndefined)); + ASSERT_EQ(CompactValue::ofAuto(), CompactValue(YGValueAuto)); + ASSERT_EQ( + CompactValue::of(-9876.5f), + CompactValue(YGValue{-9876.5f, YGUnitPoint})); + ASSERT_EQ( + CompactValue::of(123.456f), + CompactValue(YGValue{123.456f, YGUnitPercent})); +} + +TEST(YogaTest, dedicated_unit_maybe_factories) { + ASSERT_EQ( + CompactValue::ofMaybe(-9876.5f), + CompactValue(YGValue{-9876.5f, YGUnitPoint})); + ASSERT_EQ( + CompactValue::ofMaybe(YGUndefined), + CompactValue(YGValueUndefined)); + ASSERT_EQ( + CompactValue::ofMaybe(123.456f), + CompactValue(YGValue{123.456f, YGUnitPercent})); + ASSERT_EQ( + CompactValue::ofMaybe(YGUndefined), + CompactValue(YGValueUndefined)); +} + +TEST(YogaTest, can_be_assigned_from_YGValue) { + CompactValue c{}; + + YGValue v{2.0f, YGUnitPercent}; + c = v; + ASSERT_EQ((YGValue)c, v); + + c = YGValue{123, YGUnitPoint}; + ASSERT_EQ((YGValue)c, (YGValue{123, YGUnitPoint})); +} + +TEST(YogaTest, compact_value_bound_representations) { + ASSERT_EQ( + CompactValue::of(CompactValue::LOWER_BOUND).repr(), + uint32_t{0}); + ASSERT_EQ( + CompactValue::of(CompactValue::UPPER_BOUND_POINT).repr(), + uint32_t{0x3fffffff}); + ASSERT_EQ( + CompactValue::of(CompactValue::LOWER_BOUND).repr(), + uint32_t{0x40000000}); + ASSERT_EQ( + CompactValue::of(CompactValue::UPPER_BOUND_PERCENT).repr(), + uint32_t{0x7f7fffff}); + + ASSERT_EQ( + CompactValue::of(-CompactValue::LOWER_BOUND).repr(), + uint32_t{0x80000000}); + ASSERT_EQ( + CompactValue::of(-CompactValue::UPPER_BOUND_POINT).repr(), + uint32_t{0xbfffffff}); + ASSERT_EQ( + CompactValue::of(-CompactValue::LOWER_BOUND).repr(), + uint32_t{0xc0000000}); + ASSERT_EQ( + CompactValue::of(-CompactValue::UPPER_BOUND_PERCENT) + .repr(), + uint32_t{0xff7fffff}); +} diff --git a/yoga/CompactValue.h b/yoga/CompactValue.h new file mode 100644 index 00000000..1ca9d619 --- /dev/null +++ b/yoga/CompactValue.h @@ -0,0 +1,182 @@ +/** + * Copyright (c) Facebook, Inc. and its 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 + +static_assert( + std::numeric_limits::is_iec559, + "facebook::yoga::detail::CompactValue only works with IEEE754 floats"); + +#ifdef YOGA_COMPACT_VALUE_TEST +#define VISIBLE_FOR_TESTING public: +#else +#define VISIBLE_FOR_TESTING private: +#endif + +namespace facebook { +namespace yoga { +namespace detail { + +// This class stores YGValue in 32 bits. +// - The value does not matter for Undefined and Auto. NaNs are used for their +// representation. +// - To differentiate between Point and Percent, one exponent bit is used. +// Supported the range [0x40, 0xbf] (0xbf is inclusive for point, but +// exclusive for percent). +// - Value ranges: +// points: 1.08420217e-19f to 36893485948395847680 +// 0x00000000 0x3fffffff +// percent: 1.08420217e-19f to 18446742974197923840 +// 0x40000000 0x7f7fffff +// - Zero is supported, negative zero is not +// - values outside of the representable range are clamped +class CompactValue { + friend constexpr bool operator==(CompactValue, CompactValue) noexcept; + + public: + static constexpr auto LOWER_BOUND = 1.08420217e-19f; + static constexpr auto UPPER_BOUND_POINT = 36893485948395847680.0f; + static constexpr auto UPPER_BOUND_PERCENT = 18446742974197923840.0f; + + template + static CompactValue of(float value) noexcept { + if (value == 0.0f || (value < LOWER_BOUND && value > -LOWER_BOUND)) { + constexpr auto zero = + Unit == YGUnitPercent ? ZERO_BITS_PERCENT : ZERO_BITS_POINT; + return {Payload{zero}}; + } + + constexpr auto upperBound = + Unit == YGUnitPercent ? UPPER_BOUND_PERCENT : UPPER_BOUND_POINT; + if (value > upperBound || value < -upperBound) { + value = copysignf(upperBound, value); + } + + uint32_t unitBit = Unit == YGUnitPercent ? PERCENT_BIT : 0; + auto data = Payload{value}; + data.repr -= BIAS; + data.repr |= unitBit; + return {data}; + } + + template + static CompactValue ofMaybe(float value) noexcept { + return std::isnan(value) ? ofUndefined() : of(value); + } + + static constexpr CompactValue ofUndefined() noexcept { + return CompactValue{}; + } + + static constexpr CompactValue ofAuto() noexcept { + return CompactValue{Payload{AUTO_BITS}}; + } + + constexpr CompactValue() noexcept + : payload_(std::numeric_limits::quiet_NaN()) {} + + CompactValue(const YGValue& x) noexcept : payload_(uint32_t{0}) { + switch (x.unit) { + case YGUnitUndefined: + *this = ofUndefined(); + break; + case YGUnitAuto: + *this = ofAuto(); + break; + case YGUnitPoint: + *this = of(x.value); + break; + case YGUnitPercent: + *this = of(x.value); + break; + } + } + + operator YGValue() const noexcept { + switch (payload_.repr) { + case AUTO_BITS: + return YGValueAuto; + case ZERO_BITS_POINT: + return YGValue{0.0f, YGUnitPoint}; + case ZERO_BITS_PERCENT: + return YGValue{0.0f, YGUnitPercent}; + } + + if (std::isnan(payload_.value)) { + return YGValueUndefined; + } + + auto data = payload_; + data.repr &= ~PERCENT_BIT; + data.repr += BIAS; + + return YGValue{data.value, + payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint}; + } + + bool isUndefined() const noexcept { + return ( + payload_.repr != AUTO_BITS && payload_.repr != ZERO_BITS_POINT && + payload_.repr != ZERO_BITS_PERCENT && std::isnan(payload_.value)); + } + + bool isAuto() const noexcept { + return payload_.repr == AUTO_BITS; + } + + private: + union Payload { + float value; + uint32_t repr; + Payload() = delete; + constexpr Payload(uint32_t r) : repr(r) {} + constexpr Payload(float v) : value(v) {} + }; + + static constexpr uint32_t BIAS = 0x20000000; + static constexpr uint32_t PERCENT_BIT = 0x40000000; + + // these are signaling NaNs with specific bit pattern as payload + // they will be silenced whenever going through an FPU operation on ARM + x86 + static constexpr uint32_t AUTO_BITS = 0x7faaaaaa; + static constexpr uint32_t ZERO_BITS_POINT = 0x7f8f0f0f; + static constexpr uint32_t ZERO_BITS_PERCENT = 0x7f80f0f0; + + constexpr CompactValue(Payload data) noexcept : payload_(data) {} + + Payload payload_; + + VISIBLE_FOR_TESTING uint32_t repr() { + return payload_.repr; + } +}; + +template <> +CompactValue CompactValue::of(float) noexcept = delete; +template <> +CompactValue CompactValue::of(float) noexcept = delete; +template <> +CompactValue CompactValue::ofMaybe(float) noexcept = delete; +template <> +CompactValue CompactValue::ofMaybe(float) noexcept = delete; + +constexpr bool operator==(CompactValue a, CompactValue b) noexcept { + return a.payload_.repr == b.payload_.repr; +} + +constexpr bool operator!=(CompactValue a, CompactValue b) noexcept { + return !(a == b); +} + +} // namespace detail +} // namespace yoga +} // namespace facebook -- 2.50.1.windows.1 From 3df41aefdbec2772c36261a93966de8c0b8a6e08 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 14 Dec 2018 09:20:27 -0800 Subject: [PATCH 44/53] Encapsulate arrays of `YGValue` within `YGStyle` Summary: @public Enforce more encapsulation of arrays of `YGValue` in `YGSty;e`. This will allow us to use `CompactValue` in `YGStyle` while (mostly) retaining API compatibility. Reviewed By: SidharthGuglani Differential Revision: D13452042 fbshipit-source-id: 382b1c7245c4bea4280126ab1413e7e931b62eaa --- yoga/YGStyle.cpp | 26 +++++++---------- yoga/YGStyle.h | 34 ++++++++-------------- yoga/YGValue.h | 2 ++ yoga/Yoga-internal.h | 69 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 83 insertions(+), 48 deletions(-) diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp index 78df8b01..1c06cd35 100644 --- a/yoga/YGStyle.cpp +++ b/yoga/YGStyle.cpp @@ -15,39 +15,35 @@ bool YGStyle::operator==(const YGStyle& style) { alignSelf == style.alignSelf && positionType == style.positionType && flexWrap == style.flexWrap && overflow == style.overflow && display == style.display && YGValueEqual(flexBasis, style.flexBasis) && - YGValueArrayEqual(margin, style.margin) && - YGValueArrayEqual(position, style.position) && - YGValueArrayEqual(padding, style.padding) && - YGValueArrayEqual(border, style.border) && - YGValueArrayEqual(dimensions, style.dimensions) && - YGValueArrayEqual(minDimensions, style.minDimensions) && - YGValueArrayEqual(maxDimensions, style.maxDimensions); + margin == style.margin && position == style.position && + padding == style.padding && border == style.border && + dimensions == style.dimensions && minDimensions == style.minDimensions && + maxDimensions == style.maxDimensions; areNonFloatValuesEqual = areNonFloatValuesEqual && flex.isUndefined() == style.flex.isUndefined(); if (areNonFloatValuesEqual && !flex.isUndefined() && !style.flex.isUndefined()) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && flex == style.flex; + areNonFloatValuesEqual = areNonFloatValuesEqual && flex == style.flex; } areNonFloatValuesEqual = areNonFloatValuesEqual && flexGrow.isUndefined() == style.flexGrow.isUndefined(); if (areNonFloatValuesEqual && !flexGrow.isUndefined()) { - areNonFloatValuesEqual = areNonFloatValuesEqual && - flexGrow == style.flexGrow; + areNonFloatValuesEqual = + areNonFloatValuesEqual && flexGrow == style.flexGrow; } areNonFloatValuesEqual = areNonFloatValuesEqual && flexShrink.isUndefined() == style.flexShrink.isUndefined(); if (areNonFloatValuesEqual && !style.flexShrink.isUndefined()) { - areNonFloatValuesEqual = areNonFloatValuesEqual && - flexShrink == style.flexShrink; + areNonFloatValuesEqual = + areNonFloatValuesEqual && flexShrink == style.flexShrink; } if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) { - areNonFloatValuesEqual = areNonFloatValuesEqual && - aspectRatio == style.aspectRatio; + areNonFloatValuesEqual = + areNonFloatValuesEqual && aspectRatio == style.aspectRatio; } return areNonFloatValuesEqual; diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index c4f7e3c7..63b255de 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -5,6 +5,9 @@ * file in the root directory of this source tree. */ #pragma once +#include +#include +#include #include "YGFloatOptional.h" #include "Yoga-internal.h" #include "Yoga.h" @@ -13,22 +16,9 @@ constexpr YGValue kYGValueUndefined = {0, YGUnitUndefined}; constexpr YGValue kYGValueAuto = {0, YGUnitAuto}; -constexpr std::array kYGDefaultEdgeValuesUnit = { - {kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined, - kYGValueUndefined}}; - -constexpr std::array kYGDefaultDimensionValuesUnit = { - {kYGValueUndefined, kYGValueUndefined}}; - struct YGStyle { - using Dimensions = std::array; + using Dimensions = facebook::yoga::detail::Values<2>; + using Edges = facebook::yoga::detail::Values; YGDirection direction : 2; YGFlexDirection flexDirection : 2; @@ -44,13 +34,13 @@ struct YGStyle { YGFloatOptional flexGrow = {}; YGFloatOptional flexShrink = {}; YGValue flexBasis = kYGValueAuto; - std::array margin = kYGDefaultEdgeValuesUnit; - std::array position = kYGDefaultEdgeValuesUnit; - std::array padding = kYGDefaultEdgeValuesUnit; - std::array border = kYGDefaultEdgeValuesUnit; - Dimensions dimensions = {{kYGValueAuto, kYGValueAuto}}; - Dimensions minDimensions = kYGDefaultDimensionValuesUnit; - Dimensions maxDimensions = kYGDefaultDimensionValuesUnit; + Edges margin{kYGValueUndefined}; + Edges position{kYGValueUndefined}; + Edges padding{kYGValueUndefined}; + Edges border{kYGValueUndefined}; + Dimensions dimensions{kYGValueAuto}; + Dimensions minDimensions{kYGValueUndefined}; + Dimensions maxDimensions{kYGValueUndefined}; // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio = {}; diff --git a/yoga/YGValue.h b/yoga/YGValue.h index 59440be3..c3df5fc9 100644 --- a/yoga/YGValue.h +++ b/yoga/YGValue.h @@ -46,6 +46,8 @@ inline bool operator==(const YGValue& lhs, const YGValue& rhs) { case YGUnitPercent: return lhs.value == rhs.value; } + + return false; } inline bool operator!=(const YGValue& lhs, const YGValue& rhs) { diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index ef5e5d8c..cc4da004 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -42,17 +42,6 @@ extern const YGValue YGValueUndefined; extern const YGValue YGValueAuto; extern const YGValue YGValueZero; -template -bool YGValueArrayEqual( - const std::array val1, - const std::array val2) { - bool areEqual = true; - for (uint32_t i = 0; i < size && areEqual; ++i) { - areEqual = YGValueEqual(val1[i], val2[i]); - } - return areEqual; -} - struct YGCachedMeasurement { float availableWidth; float availableHeight; @@ -99,6 +88,64 @@ struct YGCachedMeasurement { // layouts should not require more than 16 entries to fit within the cache. #define YG_MAX_CACHED_RESULT_COUNT 16 +namespace facebook { +namespace yoga { +namespace detail { + +template +class Values { + private: + std::array values_; + + public: + Values() = default; + explicit Values(const YGValue& defaultValue) noexcept { + values_.fill(defaultValue); + } + + operator const std::array&() const noexcept { + return values_; + } + operator std::array&() noexcept { + return values_; + } + const YGValue& operator[](size_t i) const noexcept { + return values_[i]; + } + YGValue& operator[](size_t i) noexcept { + return values_[i]; + } + + template + YGValue get() const noexcept { + return std::get(values_); + } + + template + void set(YGValue& value) noexcept { + std::get(values_) = value; + } + + bool operator==(const Values& other) const noexcept { + for (size_t i = 0; i < Size; ++i) { + if (values_[i] != other.values_[i]) { + return false; + } + } + return true; + } + + Values& operator=(const Values& other) = default; + Values& operator=(const std::array& other) noexcept { + values_ = other; + return *this; + } +}; + +} // namespace detail +} // namespace yoga +} // namespace facebook + static const float kDefaultFlexGrow = 0.0f; static const float kDefaultFlexShrink = 0.0f; static const float kWebDefaultFlexShrink = 1.0f; -- 2.50.1.windows.1 From 8461aeaef0ee5b34ff9128777d6951effe968b13 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 14 Dec 2018 09:20:27 -0800 Subject: [PATCH 45/53] Remove cast from `detail::Values` to `std::array` will do actual work. In order to avoid that from happening implicitely, we remove the casting operator. Reviewed By: SidharthGuglani Differential Revision: D13464292 fbshipit-source-id: 217065b001a63cfa8adde715063682c583007a4d --- yoga/YGNodePrint.cpp | 7 ++++--- yoga/Yoga-internal.h | 12 +----------- yoga/Yoga.cpp | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 753a00b6..03bff15a 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -20,7 +20,8 @@ static void indent(string& base, uint32_t level) { } } -static bool areFourValuesEqual(const std::array& four) { +static bool areFourValuesEqual( + const facebook::yoga::detail::Values& four) { return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) && YGValueEqual(four[0], four[3]); } @@ -81,7 +82,7 @@ appendNumberIfNotZero(string& base, const string& str, const YGValue number) { static void appendEdges( string& base, const string& key, - const std::array& edges) { + const facebook::yoga::detail::Values& edges) { if (areFourValuesEqual(edges)) { appendNumberIfNotZero(base, key, edges[YGEdgeLeft]); } else { @@ -95,7 +96,7 @@ static void appendEdges( static void appendEdgeIfNotUndefined( string& base, const string& str, - const std::array& edges, + const facebook::yoga::detail::Values& edges, const YGEdge edge) { appendNumberIfNotUndefined( base, str, *YGComputedEdgeValue(edges, edge, &YGValueUndefined)); diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index cc4da004..719d7b37 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -103,12 +103,6 @@ class Values { values_.fill(defaultValue); } - operator const std::array&() const noexcept { - return values_; - } - operator std::array&() noexcept { - return values_; - } const YGValue& operator[](size_t i) const noexcept { return values_[i]; } @@ -136,10 +130,6 @@ class Values { } Values& operator=(const Values& other) = default; - Values& operator=(const std::array& other) noexcept { - values_ = other; - return *this; - } }; } // namespace detail @@ -153,6 +143,6 @@ 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 const YGValue* YGComputedEdgeValue( - const std::array& edges, + const facebook::yoga::detail::Values& edges, const YGEdge edge, const YGValue* const defaultValue); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 4a1a98a2..beb01c59 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -103,7 +103,7 @@ bool YGFloatIsUndefined(const float value) { } const YGValue* YGComputedEdgeValue( - const std::array& edges, + const facebook::yoga::detail::Values& edges, const YGEdge edge, const YGValue* const defaultValue) { if (edges[edge].unit != YGUnitUndefined) { -- 2.50.1.windows.1 From 885b4cbdfb73bad75edc53b73b6a076af74c94b0 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Tue, 18 Dec 2018 08:11:24 -0800 Subject: [PATCH 46/53] Switch storage in `YGStyle` to `CompactValue` Summary: @public Switches the storage in `facebook::yoga::detail::Values` from `YGValue` to `facebook::yoga::detail::CompactValue`. This cuts heap size for arrays of values in half. Reviewed By: SidharthGuglani Differential Revision: D13465586 fbshipit-source-id: 49a4d6d29a73bdd44843b1f3c57bf746050c94d6 --- yoga/CompactValue.h | 6 +- yoga/Utils.h | 6 +- yoga/YGNode.cpp | 119 ++++++++++++------------ yoga/YGNodePrint.cpp | 4 +- yoga/YGStyle.h | 21 +++-- yoga/Yoga-internal.h | 18 ++-- yoga/Yoga.cpp | 212 ++++++++++++++++++++----------------------- 7 files changed, 195 insertions(+), 191 deletions(-) diff --git a/yoga/CompactValue.h b/yoga/CompactValue.h index 1ca9d619..7120f1c1 100644 --- a/yoga/CompactValue.h +++ b/yoga/CompactValue.h @@ -6,7 +6,7 @@ */ #pragma once -#include +#include "YGValue.h" #include #include @@ -73,6 +73,10 @@ class CompactValue { return std::isnan(value) ? ofUndefined() : of(value); } + static constexpr CompactValue ofZero() noexcept { + return CompactValue{Payload{ZERO_BITS_POINT}}; + } + static constexpr CompactValue ofUndefined() noexcept { return CompactValue{}; } diff --git a/yoga/Utils.h b/yoga/Utils.h index a0d49235..7e5a8636 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -7,6 +7,7 @@ #pragma once #include "YGNode.h" #include "Yoga-internal.h" +#include "CompactValue.h" // This struct is an helper model to hold the data for step 4 of flexbox // algo, which is collecting the flex items in a line. @@ -124,8 +125,7 @@ inline YGFlexDirection YGResolveFlexDirection( } inline YGFloatOptional YGResolveValueMargin( - const YGValue value, + yoga::detail::CompactValue value, const float ownerSize) { - return value.unit == YGUnitAuto ? YGFloatOptional(0) - : YGResolveValue(value, ownerSize); + return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize); } diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 1a08fab8..8e7e210b 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -6,87 +6,92 @@ */ #include "YGNode.h" #include +#include "CompactValue.h" #include "Utils.h" using namespace facebook; +using facebook::yoga::detail::CompactValue; YGFloatOptional YGNode::getLeadingPosition( const YGFlexDirection axis, const float axisSize) const { if (YGFlexDirectionIsRow(axis)) { - const YGValue* leadingPosition = - YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined); - if (leadingPosition->unit != YGUnitUndefined) { - return YGResolveValue(*leadingPosition, axisSize); + auto leadingPosition = YGComputedEdgeValue( + style_.position, YGEdgeStart, CompactValue::ofUndefined()); + if (!leadingPosition.isUndefined()) { + return YGResolveValue(leadingPosition, axisSize); } } - const YGValue* leadingPosition = - YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined); + auto leadingPosition = YGComputedEdgeValue( + style_.position, leading[axis], CompactValue::ofUndefined()); - return leadingPosition->unit == YGUnitUndefined - ? YGFloatOptional(0) - : YGResolveValue(*leadingPosition, axisSize); + return leadingPosition.isUndefined() + ? YGFloatOptional{0} + : YGResolveValue(leadingPosition, axisSize); } YGFloatOptional YGNode::getTrailingPosition( const YGFlexDirection axis, const float axisSize) const { if (YGFlexDirectionIsRow(axis)) { - const YGValue* trailingPosition = - YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined); - if (trailingPosition->unit != YGUnitUndefined) { - return YGResolveValue(*trailingPosition, axisSize); + auto trailingPosition = YGComputedEdgeValue( + style_.position, YGEdgeEnd, CompactValue::ofUndefined()); + if (!trailingPosition.isUndefined()) { + return YGResolveValue(trailingPosition, axisSize); } } - const YGValue* trailingPosition = - YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined); + auto trailingPosition = YGComputedEdgeValue( + style_.position, trailing[axis], CompactValue::ofUndefined()); - return trailingPosition->unit == YGUnitUndefined - ? YGFloatOptional(0) - : YGResolveValue(*trailingPosition, axisSize); + return trailingPosition.isUndefined() + ? YGFloatOptional{0} + : YGResolveValue(trailingPosition, axisSize); } bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const { return (YGFlexDirectionIsRow(axis) && - YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined) - ->unit != YGUnitUndefined) || - YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined) - ->unit != YGUnitUndefined; + !YGComputedEdgeValue( + style_.position, YGEdgeStart, CompactValue::ofUndefined()) + .isUndefined()) || + !YGComputedEdgeValue( + style_.position, leading[axis], CompactValue::ofUndefined()) + .isUndefined(); } bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const { return (YGFlexDirectionIsRow(axis) && - YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined) - ->unit != YGUnitUndefined) || - YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined) - ->unit != YGUnitUndefined; + !YGComputedEdgeValue( + style_.position, YGEdgeEnd, CompactValue::ofUndefined()) + .isUndefined()) || + !YGComputedEdgeValue( + style_.position, trailing[axis], CompactValue::ofUndefined()) + .isUndefined(); } YGFloatOptional YGNode::getLeadingMargin( const YGFlexDirection axis, const float widthSize) const { - if (YGFlexDirectionIsRow(axis) && - style_.margin[YGEdgeStart].unit != YGUnitUndefined) { + if (YGFlexDirectionIsRow(axis) && !style_.margin[YGEdgeStart].isUndefined()) { return YGResolveValueMargin(style_.margin[YGEdgeStart], widthSize); } return YGResolveValueMargin( - *YGComputedEdgeValue(style_.margin, leading[axis], &YGValueZero), + YGComputedEdgeValue(style_.margin, leading[axis], CompactValue::ofZero()), widthSize); } YGFloatOptional YGNode::getTrailingMargin( const YGFlexDirection axis, const float widthSize) const { - if (YGFlexDirectionIsRow(axis) && - style_.margin[YGEdgeEnd].unit != YGUnitUndefined) { + if (YGFlexDirectionIsRow(axis) && !style_.margin[YGEdgeEnd].isUndefined()) { return YGResolveValueMargin(style_.margin[YGEdgeEnd], widthSize); } return YGResolveValueMargin( - *YGComputedEdgeValue(style_.margin, trailing[axis], &YGValueZero), + YGComputedEdgeValue( + style_.margin, trailing[axis], CompactValue::ofZero()), widthSize); } @@ -280,8 +285,7 @@ YGNode& YGNode::operator=(const YGNode& node) { } YGValue YGNode::marginLeadingValue(const YGFlexDirection axis) const { - if (YGFlexDirectionIsRow(axis) && - style_.margin[YGEdgeStart].unit != YGUnitUndefined) { + if (YGFlexDirectionIsRow(axis) && !style_.margin[YGEdgeStart].isUndefined()) { return style_.margin[YGEdgeStart]; } else { return style_.margin[leading[axis]]; @@ -289,8 +293,7 @@ YGValue YGNode::marginLeadingValue(const YGFlexDirection axis) const { } YGValue YGNode::marginTrailingValue(const YGFlexDirection axis) const { - if (YGFlexDirectionIsRow(axis) && - style_.margin[YGEdgeEnd].unit != YGUnitUndefined) { + if (YGFlexDirectionIsRow(axis) && !style_.margin[YGEdgeEnd].isUndefined()) { return style_.margin[YGEdgeEnd]; } else { return style_.margin[trailing[axis]]; @@ -310,7 +313,7 @@ YGValue YGNode::resolveFlexBasisPtr() const { void YGNode::resolveDimension() { for (uint32_t dim = YGDimensionWidth; dim < YGDimensionCount; dim++) { - if (getStyle().maxDimensions[dim].unit != YGUnitUndefined && + if (!getStyle().maxDimensions[dim].isUndefined() && YGValueEqual( getStyle().maxDimensions[dim], style_.minDimensions[dim])) { resolvedDimensions_[dim] = style_.maxDimensions[dim]; @@ -422,30 +425,32 @@ bool YGNode::isNodeFlexible() { } float YGNode::getLeadingBorder(const YGFlexDirection axis) const { - if (YGFlexDirectionIsRow(axis) && - style_.border[YGEdgeStart].unit != YGUnitUndefined && - !yoga::isUndefined(style_.border[YGEdgeStart].value) && - style_.border[YGEdgeStart].value >= 0.0f) { - return style_.border[YGEdgeStart].value; + YGValue leadingBorder; + if (YGFlexDirectionIsRow(axis) && !style_.border[YGEdgeStart].isUndefined()) { + leadingBorder = style_.border[YGEdgeStart]; + if (leadingBorder.value >= 0) { + return leadingBorder.value; + } } - float computedEdgeValue = - YGComputedEdgeValue(style_.border, leading[axis], &YGValueZero)->value; - return YGFloatMax(computedEdgeValue, 0.0f); + leadingBorder = + YGComputedEdgeValue(style_.border, leading[axis], CompactValue::ofZero()); + return YGFloatMax(leadingBorder.value, 0.0f); } float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const { + YGValue trailingBorder; if (YGFlexDirectionIsRow(flexDirection) && - style_.border[YGEdgeEnd].unit != YGUnitUndefined && - !yoga::isUndefined(style_.border[YGEdgeEnd].value) && - style_.border[YGEdgeEnd].value >= 0.0f) { - return style_.border[YGEdgeEnd].value; + !style_.border[YGEdgeEnd].isUndefined()) { + trailingBorder = style_.border[YGEdgeEnd]; + if (trailingBorder.value >= 0.0f) { + return trailingBorder.value; + } } - float computedEdgeValue = - YGComputedEdgeValue(style_.border, trailing[flexDirection], &YGValueZero) - ->value; - return YGFloatMax(computedEdgeValue, 0.0f); + trailingBorder = YGComputedEdgeValue( + style_.border, trailing[flexDirection], CompactValue::ofZero()); + return YGFloatMax(trailingBorder.value, 0.0f); } YGFloatOptional YGNode::getLeadingPadding( @@ -454,13 +459,14 @@ YGFloatOptional YGNode::getLeadingPadding( const YGFloatOptional paddingEdgeStart = YGResolveValue(style_.padding[YGEdgeStart], widthSize); if (YGFlexDirectionIsRow(axis) && - style_.padding[YGEdgeStart].unit != YGUnitUndefined && + !style_.padding[YGEdgeStart].isUndefined() && !paddingEdgeStart.isUndefined() && paddingEdgeStart.unwrap() >= 0.0f) { return paddingEdgeStart; } YGFloatOptional resolvedValue = YGResolveValue( - *YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero), + YGComputedEdgeValue( + style_.padding, leading[axis], CompactValue::ofZero()), widthSize); return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); } @@ -475,7 +481,8 @@ YGFloatOptional YGNode::getTrailingPadding( } YGFloatOptional resolvedValue = YGResolveValue( - *YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero), + YGComputedEdgeValue( + style_.padding, trailing[axis], CompactValue::ofZero()), widthSize); return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 03bff15a..4be2ff5a 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -99,7 +99,9 @@ static void appendEdgeIfNotUndefined( const facebook::yoga::detail::Values& edges, const YGEdge edge) { appendNumberIfNotUndefined( - base, str, *YGComputedEdgeValue(edges, edge, &YGValueUndefined)); + base, + str, + YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined())); } void YGNodeToString( diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index 63b255de..abcc7052 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -8,6 +8,7 @@ #include #include #include +#include "CompactValue.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" #include "Yoga.h" @@ -17,6 +18,10 @@ constexpr YGValue kYGValueUndefined = {0, YGUnitUndefined}; constexpr YGValue kYGValueAuto = {0, YGUnitAuto}; struct YGStyle { + private: + using CompactValue = facebook::yoga::detail::CompactValue; + + public: using Dimensions = facebook::yoga::detail::Values<2>; using Edges = facebook::yoga::detail::Values; @@ -33,14 +38,14 @@ struct YGStyle { YGFloatOptional flex = {}; YGFloatOptional flexGrow = {}; YGFloatOptional flexShrink = {}; - YGValue flexBasis = kYGValueAuto; - Edges margin{kYGValueUndefined}; - Edges position{kYGValueUndefined}; - Edges padding{kYGValueUndefined}; - Edges border{kYGValueUndefined}; - Dimensions dimensions{kYGValueAuto}; - Dimensions minDimensions{kYGValueUndefined}; - Dimensions maxDimensions{kYGValueUndefined}; + CompactValue flexBasis = CompactValue::ofAuto(); + Edges margin = {}; + Edges position = {}; + Edges padding = {}; + Edges border = {}; + Dimensions dimensions{CompactValue::ofAuto()}; + Dimensions minDimensions = {}; + Dimensions maxDimensions = {}; // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio = {}; diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 719d7b37..a182a465 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -9,6 +9,7 @@ #include #include #include +#include "CompactValue.h" #include "Yoga.h" using YGVector = std::vector; @@ -95,7 +96,7 @@ namespace detail { template class Values { private: - std::array values_; + std::array values_; public: Values() = default; @@ -103,10 +104,10 @@ class Values { values_.fill(defaultValue); } - const YGValue& operator[](size_t i) const noexcept { + const CompactValue& operator[](size_t i) const noexcept { return values_[i]; } - YGValue& operator[](size_t i) noexcept { + CompactValue& operator[](size_t i) noexcept { return values_[i]; } @@ -120,6 +121,11 @@ class Values { std::get(values_) = value; } + template + void set(YGValue&& value) noexcept { + set(value); + } + bool operator==(const Values& other) const noexcept { for (size_t i = 0; i < Size; ++i) { if (values_[i] != other.values_[i]) { @@ -142,7 +148,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 const YGValue* YGComputedEdgeValue( +extern facebook::yoga::detail::CompactValue YGComputedEdgeValue( const facebook::yoga::detail::Values& edges, - const YGEdge edge, - const YGValue* const defaultValue); + YGEdge edge, + facebook::yoga::detail::CompactValue defaultValue); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index beb01c59..9b8aa8a4 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -23,6 +23,8 @@ __forceinline const float fmaxf(const float a, const float b) { #endif #endif +using namespace facebook::yoga; + #ifdef ANDROID static int YGAndroidLog( const YGConfigRef config, @@ -102,31 +104,31 @@ bool YGFloatIsUndefined(const float value) { return facebook::yoga::isUndefined(value); } -const YGValue* YGComputedEdgeValue( +detail::CompactValue YGComputedEdgeValue( const facebook::yoga::detail::Values& edges, - const YGEdge edge, - const YGValue* const defaultValue) { - if (edges[edge].unit != YGUnitUndefined) { - return &edges[edge]; + YGEdge edge, + detail::CompactValue defaultValue) { + if (!edges[edge].isUndefined()) { + return edges[edge]; } if ((edge == YGEdgeTop || edge == YGEdgeBottom) && - edges[YGEdgeVertical].unit != YGUnitUndefined) { - return &edges[YGEdgeVertical]; + !edges[YGEdgeVertical].isUndefined()) { + return edges[YGEdgeVertical]; } if ((edge == YGEdgeLeft || edge == YGEdgeRight || edge == YGEdgeStart || edge == YGEdgeEnd) && - edges[YGEdgeHorizontal].unit != YGUnitUndefined) { - return &edges[YGEdgeHorizontal]; + !edges[YGEdgeHorizontal].isUndefined()) { + return edges[YGEdgeHorizontal]; } - if (edges[YGEdgeAll].unit != YGUnitUndefined) { - return &edges[YGEdgeAll]; + if (!edges[YGEdgeAll].isUndefined()) { + return edges[YGEdgeAll]; } if (edge == YGEdgeStart || edge == YGEdgeEnd) { - return &YGValueUndefined; + return detail::CompactValue::ofUndefined(); } return defaultValue; @@ -595,14 +597,21 @@ namespace { struct Value { template - static YGValue create(float value) { - return { - YGFloatSanitize(value), - YGFloatIsUndefined(value) ? YGUnitUndefined : U, - }; + static detail::CompactValue create(float value) { + return detail::CompactValue::ofMaybe(value); } }; +template <> +inline detail::CompactValue Value::create(float) { + return detail::CompactValue::ofUndefined(); +} + +template <> +inline detail::CompactValue Value::create(float) { + return detail::CompactValue::ofAuto(); +} + template struct DimensionProp { template @@ -616,10 +625,8 @@ struct DimensionProp { template static void set(YGNodeRef node, float newValue) { - YGValue value = Value::create(newValue); - if (((node->getStyle().*P)[idx].value != value.value && - value.unit != YGUnitUndefined) || - (node->getStyle().*P)[idx].unit != value.unit) { + auto value = Value::create(newValue); + if ((node->getStyle().*P)[idx] != value) { (node->getStyle().*P)[idx] = value; node->markDirtyAndPropogate(); } @@ -628,37 +635,30 @@ struct DimensionProp { } // namespace -#define YG_NODE_STYLE_PROPERTY_SETTER_UNIT_AUTO_IMPL( \ - type, name, paramName, instanceName) \ - void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ - YGValue value = { \ - YGFloatSanitize(paramName), \ - YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \ - }; \ - if ((node->getStyle().instanceName.value != value.value && \ - value.unit != YGUnitUndefined) || \ - node->getStyle().instanceName.unit != value.unit) { \ - node->getStyle().instanceName = value; \ - node->markDirtyAndPropogate(); \ - } \ - } \ - \ - void YGNodeStyleSet##name##Percent( \ - const YGNodeRef node, const type paramName) { \ - if (node->getStyle().instanceName.value != YGFloatSanitize(paramName) || \ - node->getStyle().instanceName.unit != YGUnitPercent) { \ - node->getStyle().instanceName = YGFloatIsUndefined(paramName) \ - ? YGValue{0, YGUnitAuto} \ - : YGValue{paramName, YGUnitPercent}; \ - node->markDirtyAndPropogate(); \ - } \ - } \ - \ - void YGNodeStyleSet##name##Auto(const YGNodeRef node) { \ - if (node->getStyle().instanceName.unit != YGUnitAuto) { \ - node->getStyle().instanceName = {0, YGUnitAuto}; \ - node->markDirtyAndPropogate(); \ - } \ +#define YG_NODE_STYLE_PROPERTY_SETTER_UNIT_AUTO_IMPL( \ + type, name, paramName, instanceName) \ + void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ + auto value = detail::CompactValue::ofMaybe(paramName); \ + if (node->getStyle().instanceName != value) { \ + node->getStyle().instanceName = value; \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Percent( \ + const YGNodeRef node, const type paramName) { \ + auto value = detail::CompactValue::ofMaybe(paramName); \ + if (node->getStyle().instanceName != value) { \ + node->getStyle().instanceName = value; \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Auto(const YGNodeRef node) { \ + if (node->getStyle().instanceName != detail::CompactValue::ofAuto()) { \ + node->getStyle().instanceName = detail::CompactValue::ofAuto(); \ + node->markDirtyAndPropogate(); \ + } \ } #define YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL( \ @@ -676,49 +676,40 @@ struct DimensionProp { #define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO_IMPL(type, name, instanceName) \ void YGNodeStyleSet##name##Auto(const YGNodeRef node, const YGEdge edge) { \ - if (node->getStyle().instanceName[edge].unit != YGUnitAuto) { \ - node->getStyle().instanceName[edge] = {0, YGUnitAuto}; \ + if (node->getStyle().instanceName[edge] != \ + detail::CompactValue::ofAuto()) { \ + node->getStyle().instanceName[edge] = detail::CompactValue::ofAuto(); \ node->markDirtyAndPropogate(); \ } \ } -#define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL( \ - type, name, paramName, instanceName) \ - void YGNodeStyleSet##name( \ - const YGNodeRef node, const YGEdge edge, const float paramName) { \ - YGValue value = { \ - YGFloatSanitize(paramName), \ - YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint, \ - }; \ - if ((node->getStyle().instanceName[edge].value != value.value && \ - value.unit != YGUnitUndefined) || \ - node->getStyle().instanceName[edge].unit != value.unit) { \ - node->getStyle().instanceName[edge] = value; \ - node->markDirtyAndPropogate(); \ - } \ - } \ - \ - void YGNodeStyleSet##name##Percent( \ - const YGNodeRef node, const YGEdge edge, const float paramName) { \ - YGValue value = { \ - YGFloatSanitize(paramName), \ - YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPercent, \ - }; \ - if ((node->getStyle().instanceName[edge].value != value.value && \ - value.unit != YGUnitUndefined) || \ - node->getStyle().instanceName[edge].unit != value.unit) { \ - node->getStyle().instanceName[edge] = value; \ - node->markDirtyAndPropogate(); \ - } \ - } \ - \ - WIN_STRUCT(type) \ - YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge) { \ - YGValue value = node->getStyle().instanceName[edge]; \ - if (value.unit == YGUnitUndefined || value.unit == YGUnitAuto) { \ - value.value = YGUndefined; \ - } \ - return WIN_STRUCT_REF(value); \ +#define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL( \ + type, name, paramName, instanceName) \ + void YGNodeStyleSet##name( \ + const YGNodeRef node, const YGEdge edge, const float paramName) { \ + auto value = detail::CompactValue::ofMaybe(paramName); \ + if (node->getStyle().instanceName[edge] != value) { \ + node->getStyle().instanceName[edge] = value; \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Percent( \ + const YGNodeRef node, const YGEdge edge, const float paramName) { \ + auto value = detail::CompactValue::ofMaybe(paramName); \ + if (node->getStyle().instanceName[edge] != value) { \ + node->getStyle().instanceName[edge] = value; \ + node->markDirtyAndPropogate(); \ + } \ + } \ + \ + WIN_STRUCT(type) \ + YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge) { \ + YGValue value = node->getStyle().instanceName[edge]; \ + if (value.unit == YGUnitUndefined || value.unit == YGUnitAuto) { \ + value.value = YGUndefined; \ + } \ + return WIN_STRUCT_REF(value); \ } #define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ @@ -881,13 +872,8 @@ YGValue YGNodeStyleGetFlexBasis(const YGNodeRef node) { } void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) { - YGValue value = { - YGFloatSanitize(flexBasis), - YGFloatIsUndefined(flexBasis) ? YGUnitUndefined : YGUnitPoint, - }; - if ((node->getStyle().flexBasis.value != value.value && - value.unit != YGUnitUndefined) || - node->getStyle().flexBasis.unit != value.unit) { + auto value = detail::CompactValue::ofMaybe(flexBasis); + if (node->getStyle().flexBasis != value) { node->getStyle().flexBasis = value; node->markDirtyAndPropogate(); } @@ -896,18 +882,16 @@ void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) { void YGNodeStyleSetFlexBasisPercent( const YGNodeRef node, const float flexBasisPercent) { - if (node->getStyle().flexBasis.value != flexBasisPercent || - node->getStyle().flexBasis.unit != YGUnitPercent) { - node->getStyle().flexBasis = YGFloatIsUndefined(flexBasisPercent) - ? YGValue{0, YGUnitAuto} - : YGValue{flexBasisPercent, YGUnitPercent}; + auto value = detail::CompactValue::ofMaybe(flexBasisPercent); + if (node->getStyle().flexBasis != value) { + node->getStyle().flexBasis = value; node->markDirtyAndPropogate(); } } void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { - if (node->getStyle().flexBasis.unit != YGUnitAuto) { - node->getStyle().flexBasis = {0, YGUnitAuto}; + if (node->getStyle().flexBasis != detail::CompactValue::ofAuto()) { + node->getStyle().flexBasis = detail::CompactValue::ofAuto(); node->markDirtyAndPropogate(); } } @@ -922,27 +906,23 @@ void YGNodeStyleSetBorder( const YGNodeRef node, const YGEdge edge, const float border) { - YGValue value = { - YGFloatSanitize(border), - YGFloatIsUndefined(border) ? YGUnitUndefined : YGUnitPoint, - }; - if ((node->getStyle().border[edge].value != value.value && - value.unit != YGUnitUndefined) || - node->getStyle().border[edge].unit != value.unit) { + auto value = detail::CompactValue::ofMaybe(border); + if (node->getStyle().border[edge] != value) { node->getStyle().border[edge] = value; node->markDirtyAndPropogate(); } } float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) { - if (node->getStyle().border[edge].unit == YGUnitUndefined || - node->getStyle().border[edge].unit == YGUnitAuto) { + if (node->getStyle().border[edge].isUndefined() || + node->getStyle().border[edge].isAuto()) { // TODO(T26792433): Rather than returning YGUndefined, change the api to // return YGFloatOptional. return YGUndefined; } - return node->getStyle().border[edge].value; + auto border = (YGValue)node->getStyle().border[edge]; + return border.value; } // Yoga specific properties, not compatible with flexbox specification @@ -2433,7 +2413,7 @@ static void YGJustifyMainAxis( // remainingFreeSpace is 0 when min main dimension is not given if (measureModeMainDim == YGMeasureModeAtMost && collectedFlexItemsValues.remainingFreeSpace > 0) { - if (style.minDimensions[dim[mainAxis]].unit != YGUnitUndefined && + if (!style.minDimensions[dim[mainAxis]].isUndefined() && !YGResolveValue(style.minDimensions[dim[mainAxis]], mainAxisownerSize) .isUndefined()) { // This condition makes sure that if the size of main dimension(after -- 2.50.1.windows.1 From f6415889ca72fc7df00e3fa3cdc0fdb9f28a4d39 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Tue, 18 Dec 2018 08:11:25 -0800 Subject: [PATCH 47/53] Use bitfields for `YGLayout` and `YGNode` Summary: @public Further heap size reductions by using bitfields in `YGLayout` and `YGNode`. Reviewed By: SidharthGuglani Differential Revision: D13466325 fbshipit-source-id: ddcef0a1b3822e7449fe485d99c920d54139c893 --- yoga/YGLayout.h | 14 +++++++++----- yoga/YGNode.h | 14 +++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h index 2a0215d3..94a92adf 100644 --- a/yoga/YGLayout.h +++ b/yoga/YGLayout.h @@ -17,11 +17,13 @@ struct YGLayout { std::array margin = {}; std::array border = {}; std::array padding = {}; - YGDirection direction = YGDirectionInherit; + YGDirection direction : 2; + bool didUseLegacyFlag : 1; + bool doesLegacyStretchFlagAffectsLayout : 1; + bool hadOverflow : 1; uint32_t computedFlexBasisGeneration = 0; YGFloatOptional computedFlexBasis = {}; - bool hadOverflow = false; // Instead of recomputing the entire layout every single time, we // cache some information to break early when nothing changed @@ -34,10 +36,12 @@ struct YGLayout { std::array measuredDimensions = kYGDefaultDimensionValues; YGCachedMeasurement cachedLayout = YGCachedMeasurement(); - bool didUseLegacyFlag = false; - bool doesLegacyStretchFlagAffectsLayout = false; - YGLayout() = default; + YGLayout() + : direction(YGDirectionInherit), + didUseLegacyFlag(false), + doesLegacyStretchFlagAffectsLayout(false), + hadOverflow(false) {} bool operator==(YGLayout layout) const; bool operator!=(YGLayout layout) const { diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 57312812..2c00ec75 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -15,9 +15,10 @@ struct YGNode { private: void* context_ = nullptr; YGPrintFunc print_ = nullptr; - bool hasNewLayout_ = true; - bool isReferenceBaseline_ = false; - YGNodeType nodeType_ = YGNodeTypeDefault; + bool hasNewLayout_ : 1; + bool isReferenceBaseline_ : 1; + bool isDirty_ : 1; + YGNodeType nodeType_ : 1; YGMeasureFunc measure_ = nullptr; YGBaselineFunc baseline_ = nullptr; YGDirtiedFunc dirtied_ = nullptr; @@ -27,7 +28,6 @@ struct YGNode { YGNodeRef owner_ = nullptr; YGVector children_ = {}; YGConfigRef config_ = nullptr; - bool isDirty_ = false; std::array resolvedDimensions_ = { {YGValueUndefined, YGValueUndefined}}; @@ -36,7 +36,11 @@ struct YGNode { const float axisSize) const; public: - YGNode() = default; + YGNode() + : hasNewLayout_(true), + isReferenceBaseline_(false), + isDirty_(false), + nodeType_(YGNodeTypeDefault) {} ~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree explicit YGNode(const YGConfigRef newConfig) : config_(newConfig){}; YGNode(const YGNode& node) = default; -- 2.50.1.windows.1 From 56e133ab4c7966c0d61c0335b59beeb589d7a223 Mon Sep 17 00:00:00 2001 From: Taras Tsugrii Date: Wed, 19 Dec 2018 15:12:27 -0800 Subject: [PATCH 48/53] Do not use glob for static paths. Summary: ``` >>> Lint for xplat/yoga/csharp/BUCK: Warning (BUILDIFIERLINT2) constant-glob Glob pattern `Yoga/YGInterop.cpp` has no wildcard ('*'). Constant patterns can be error-prone, move the file outside the glob. (https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#constant-glob) 30 31 yoga_cxx_library( 32 name = "yoganet", >>> 33 srcs = glob(["Yoga/YGInterop.cpp"]), 34 compiler_flags = COMPILER_FLAGS, 35 link_style = "static", 36 link_whole = True, ``` Differential Revision: D13521382 fbshipit-source-id: 744368e7818370c8ec68f332caaf766cad635e7a --- csharp/BUCK | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/BUCK b/csharp/BUCK index 0f8a0bf8..0df9bea4 100644 --- a/csharp/BUCK +++ b/csharp/BUCK @@ -30,7 +30,7 @@ fb_native.csharp_library( yoga_cxx_library( name = "yoganet", - srcs = glob(["Yoga/YGInterop.cpp"]), + srcs = ["Yoga/YGInterop.cpp"], compiler_flags = COMPILER_FLAGS, link_style = "static", link_whole = True, -- 2.50.1.windows.1 From 5514722ce27a6c094c91a310fd27942f64f658ed Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 21 Dec 2018 03:12:17 -0800 Subject: [PATCH 49/53] Add tests for `YogaNode#hasNewLayout()` / `#markLayoutSeen()` Summary: @public Adds test for the `hasNewLayout()` and `markLayoutSeen()` methods of `YogaNode`. The behavior of these methods wasn't previously covered by a test. This will allow us to change the implementation with confidence. Reviewed By: SidharthGuglani Differential Revision: D13534351 fbshipit-source-id: 23a9f9b70df18fd7c34023fd77b9df9fbd733f61 --- .../tests/com/facebook/yoga/YogaNodeTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/java/tests/com/facebook/yoga/YogaNodeTest.java b/java/tests/com/facebook/yoga/YogaNodeTest.java index e65c4ff7..405c322e 100644 --- a/java/tests/com/facebook/yoga/YogaNodeTest.java +++ b/java/tests/com/facebook/yoga/YogaNodeTest.java @@ -386,6 +386,52 @@ public class YogaNodeTest { assertFalse(root.getDoesLegacyStretchFlagAffectsLayout()); } + @Test + public void initiallyHasNewLayout() { + YogaNode root = createNode(); + assertTrue(root.hasNewLayout()); + } + + @Test + public void initialLayoutCanBeMarkedSeen() { + YogaNode root = createNode(); + root.markLayoutSeen(); + assertFalse(root.hasNewLayout()); + } + + @Test + public void calculatingLayoutMarksLayoutAsUnseen() { + YogaNode root = createNode(); + root.markLayoutSeen(); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + assertTrue(root.hasNewLayout()); + } + + @Test + public void calculatedLayoutCanBeMarkedSeen() { + YogaNode root = createNode(); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + root.markLayoutSeen(); + assertFalse(root.hasNewLayout()); + } + + @Test + public void recalculatingLayoutDoesMarkAsUnseen() { + YogaNode root = createNode(); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + root.markLayoutSeen(); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + assertTrue(root.hasNewLayout()); + } + + @Test + public void resetAlsoResetsLayoutSeen() { + YogaNode root = createNode(); + root.markLayoutSeen(); + root.reset(); + assertTrue(root.hasNewLayout()); + } + private YogaNode createNode() { return mNodeFactory.create(); } -- 2.50.1.windows.1 From 138521ccc289c03ad18ff9ac4798e1937bf1c548 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 21 Dec 2018 03:12:17 -0800 Subject: [PATCH 50/53] Test `YogaNode#getLayoutDirection()` Summary: @public Previously untested. Allows us to ship with more confidence Reviewed By: SidharthGuglani Differential Revision: D13534350 fbshipit-source-id: a2e7577befdeeb7a27148e16624eeb7a347efd87 --- java/tests/com/facebook/yoga/YogaNodeTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/java/tests/com/facebook/yoga/YogaNodeTest.java b/java/tests/com/facebook/yoga/YogaNodeTest.java index 405c322e..a792fe52 100644 --- a/java/tests/com/facebook/yoga/YogaNodeTest.java +++ b/java/tests/com/facebook/yoga/YogaNodeTest.java @@ -432,6 +432,16 @@ public class YogaNodeTest { assertTrue(root.hasNewLayout()); } + @Test + public void directionIsPassedThrough() { + YogaNode root = createNode(); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(root.getLayoutDirection(), YogaDirection.RTL); + } + private YogaNode createNode() { return mNodeFactory.create(); } -- 2.50.1.windows.1 From b66642cb863c12ab1c2c1227b32302adee7df374 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 4 Jan 2019 06:02:41 -0800 Subject: [PATCH 51/53] fixed a csharp test case Summary: Using default logger in test case Reviewed By: davidaurelio Differential Revision: D13565071 fbshipit-source-id: 93cee223a7f366e3e965fde2d5cdc7d4b27e310f --- csharp/tests/Facebook.Yoga/YogaNodeTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/tests/Facebook.Yoga/YogaNodeTest.cs b/csharp/tests/Facebook.Yoga/YogaNodeTest.cs index eb9f1e8d..69332735 100644 --- a/csharp/tests/Facebook.Yoga/YogaNodeTest.cs +++ b/csharp/tests/Facebook.Yoga/YogaNodeTest.cs @@ -259,7 +259,7 @@ namespace Facebook.Yoga [Test] public void TestPrintWithLogger() { - YogaNode node = new YogaNode(new YogaConfig{Logger = (c, n, l, m) => {}}); + YogaNode node = new YogaNode(); node.Width = 110; node.Height = 105; node.CalculateLayout(); -- 2.50.1.windows.1 From ad86cf81628d0d6ad4e4f38313f7f92bd2a6e47d Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Sat, 5 Jan 2019 19:49:36 -0500 Subject: [PATCH 52/53] Adds fixes for react-native-windows UWP Specifically, updates the UWP .vcxproj for MSBuild and also exposes the UseLegacyStretchBehaviour API for use with react-native-windows. --- csharp/Facebook.Yoga/Native.cs | 8 +++ csharp/Facebook.Yoga/YogaConfig.cs | 15 +++++- csharp/Yoga/Yoga.Universal.vcxproj | 46 ++++++++++------ csharp/Yoga/Yoga.Universal.vcxproj.filters | 62 +++++++++++++++++----- yoga/Yoga.h | 6 +-- 5 files changed, 103 insertions(+), 34 deletions(-) diff --git a/csharp/Facebook.Yoga/Native.cs b/csharp/Facebook.Yoga/Native.cs index 02e9399d..3271c7d2 100644 --- a/csharp/Facebook.Yoga/Native.cs +++ b/csharp/Facebook.Yoga/Native.cs @@ -74,6 +74,14 @@ namespace Facebook.Yoga [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern bool YGConfigGetUseWebDefaults(YGConfigHandle config); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern void YGConfigSetUseLegacyStretchBehaviour( + YGConfigHandle config, + bool useLegacyStretchBehavior); + + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern bool YGConfigGetUseLegacyStretchBehaviour(YGConfigHandle config); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGConfigSetPointScaleFactor( YGConfigHandle config, diff --git a/csharp/Facebook.Yoga/YogaConfig.cs b/csharp/Facebook.Yoga/YogaConfig.cs index 7f175725..b8e58e09 100644 --- a/csharp/Facebook.Yoga/YogaConfig.cs +++ b/csharp/Facebook.Yoga/YogaConfig.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -117,6 +117,19 @@ namespace Facebook.Yoga } } + public bool UseLegacyStretchBehaviour + { + get + { + return Native.YGConfigGetUseLegacyStretchBehaviour(_ygConfig); + } + + set + { + Native.YGConfigSetUseLegacyStretchBehaviour(_ygConfig, value); + } + } + public float PointScaleFactor { set diff --git a/csharp/Yoga/Yoga.Universal.vcxproj b/csharp/Yoga/Yoga.Universal.vcxproj index 43d62b17..1c956466 100644 --- a/csharp/Yoga/Yoga.Universal.vcxproj +++ b/csharp/Yoga/Yoga.Universal.vcxproj @@ -1,4 +1,4 @@ - + @@ -33,47 +33,47 @@ Yoga true Windows Store - 10.0.10586.0 - 10.0.10240.0 + 10.0.14393.0 + 10.0.14393.0 10.0 DynamicLibrary true - v140 + v141 Unicode DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode DynamicLibrary false - v140 + v141 true Unicode DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode @@ -116,7 +116,7 @@ true bin\Universal\$(PlatformTarget)\$(Configuration)\ - obj\$(PlatformTarget)\$(Configuration)\ + obj\Universal\$(PlatformTarget)\$(Configuration)\ yoga @@ -242,19 +242,31 @@ + + - + + - + + + + + - - - - + + + + + + + + + false @@ -284,4 +296,4 @@ - \ No newline at end of file + diff --git a/csharp/Yoga/Yoga.Universal.vcxproj.filters b/csharp/Yoga/Yoga.Universal.vcxproj.filters index 84cee3aa..697d52c1 100644 --- a/csharp/Yoga/Yoga.Universal.vcxproj.filters +++ b/csharp/Yoga/Yoga.Universal.vcxproj.filters @@ -21,22 +21,40 @@ Header Files - + + Header Files + + + Header Files + + + Header Files + + + Header Files + + Header Files Header Files - + Header Files - + Header Files - + Header Files - + + Header Files + + + Header Files + + Header Files @@ -47,16 +65,34 @@ Source Files - - Source Files - - - Source Files - Source Files - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files @@ -65,4 +101,4 @@ Resource Files - \ No newline at end of file + diff --git a/yoga/Yoga.h b/yoga/Yoga.h index dddab8bb..237fc46b 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -174,11 +174,11 @@ YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node); void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc); YGPrintFunc YGNodeGetPrintFunc(YGNodeRef node); void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc); -bool YGNodeGetHasNewLayout(YGNodeRef node); -void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout); +WIN_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node); +WIN_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout); YGNodeType YGNodeGetNodeType(YGNodeRef node); void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType); -bool YGNodeIsDirty(YGNodeRef node); +WIN_EXPORT bool YGNodeIsDirty(YGNodeRef node); bool YGNodeLayoutGetDidUseLegacyFlag(const YGNodeRef node); WIN_EXPORT void YGNodeStyleSetDirection( -- 2.50.1.windows.1 From f29356d60ba880c599b11ac8c7a8355d9a3ac871 Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Sat, 5 Jan 2019 23:58:13 -0500 Subject: [PATCH 53/53] Remove WIN_STRUCT macro If ARM compatibility still requires the WIN_STRUCT macro, we have a lot of additional changes to make. Removing for now, as this is clearly broken for some Yoga values (e.g., margin, padding, etc.). Will follow up with another PR after validating that we still need to pass structs by ref in RS1 or later. --- csharp/Facebook.Yoga/Native.cs | 26 +++++------- csharp/Facebook.Yoga/YogaNode.Spacing.cs | 50 ++++++++++++------------ csharp/Facebook.Yoga/YogaNode.cs | 16 ++++---- csharp/Facebook.Yoga/YogaValue.cs | 12 ------ csharp/Yoga/Yoga.vcxproj | 12 +++--- yoga/YGMacros.h | 8 ---- yoga/Yoga.cpp | 4 +- yoga/Yoga.h | 2 +- 8 files changed, 52 insertions(+), 78 deletions(-) diff --git a/csharp/Facebook.Yoga/Native.cs b/csharp/Facebook.Yoga/Native.cs index 3271c7d2..7ec1ab18 100644 --- a/csharp/Facebook.Yoga/Native.cs +++ b/csharp/Facebook.Yoga/Native.cs @@ -10,12 +10,6 @@ using System.Runtime.InteropServices; namespace Facebook.Yoga { -#if WINDOWS_UWP_ARM - using YogaValueType = IntPtr; -#else - using YogaValueType = YogaValue; -#endif - internal static class Native { #if (UNITY_IOS && !UNITY_EDITOR) || __IOS__ @@ -234,7 +228,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetFlexBasisAuto(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetFlexBasis(YGNodeHandle node); + public static extern YogaValue YGNodeStyleGetFlexBasis(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetWidth(YGNodeHandle node, float width); @@ -246,7 +240,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetWidthAuto(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetWidth(YGNodeHandle node); + public static extern YogaValue YGNodeStyleGetWidth(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetHeight(YGNodeHandle node, float height); @@ -258,7 +252,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetHeightAuto(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetHeight(YGNodeHandle node); + public static extern YogaValue YGNodeStyleGetHeight(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetMinWidth(YGNodeHandle node, float minWidth); @@ -267,7 +261,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetMinWidthPercent(YGNodeHandle node, float minWidth); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetMinWidth(YGNodeHandle node); + public static extern YogaValue YGNodeStyleGetMinWidth(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetMinHeight(YGNodeHandle node, float minHeight); @@ -276,7 +270,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetMinHeightPercent(YGNodeHandle node, float minHeight); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetMinHeight(YGNodeHandle node); + public static extern YogaValue YGNodeStyleGetMinHeight(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetMaxWidth(YGNodeHandle node, float maxWidth); @@ -285,7 +279,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetMaxWidthPercent(YGNodeHandle node, float maxWidth); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetMaxWidth(YGNodeHandle node); + public static extern YogaValue YGNodeStyleGetMaxWidth(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetMaxHeight(YGNodeHandle node, float maxHeight); @@ -294,7 +288,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetMaxHeightPercent(YGNodeHandle node, float maxHeight); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetMaxHeight(YGNodeHandle node); + public static extern YogaValue YGNodeStyleGetMaxHeight(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetAspectRatio(YGNodeHandle node, float aspectRatio); @@ -313,7 +307,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetPositionPercent(YGNodeHandle node, YogaEdge edge, float position); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetPosition(YGNodeHandle node, YogaEdge edge); + public static extern YogaValue YGNodeStyleGetPosition(YGNodeHandle node, YogaEdge edge); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetMargin(YGNodeHandle node, YogaEdge edge, float margin); @@ -325,7 +319,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetMarginAuto(YGNodeHandle node, YogaEdge edge); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge); + public static extern YogaValue YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetPadding(YGNodeHandle node, YogaEdge edge, float padding); @@ -334,7 +328,7 @@ namespace Facebook.Yoga public static extern void YGNodeStyleSetPaddingPercent(YGNodeHandle node, YogaEdge edge, float padding); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - public static extern YogaValueType YGNodeStyleGetPadding(YGNodeHandle node, YogaEdge edge); + public static extern YogaValue YGNodeStyleGetPadding(YGNodeHandle node, YogaEdge edge); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetBorder(YGNodeHandle node, YogaEdge edge, float border); diff --git a/csharp/Facebook.Yoga/YogaNode.Spacing.cs b/csharp/Facebook.Yoga/YogaNode.Spacing.cs index df9157c9..d3a8f864 100644 --- a/csharp/Facebook.Yoga/YogaNode.Spacing.cs +++ b/csharp/Facebook.Yoga/YogaNode.Spacing.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -13,7 +13,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Left)); + return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Left); } set @@ -26,7 +26,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Top)); + return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Top); } set @@ -39,7 +39,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Right)); + return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Right); } set @@ -52,7 +52,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Bottom)); + return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Bottom); } set @@ -65,7 +65,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Start)); + return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Start); } set @@ -78,7 +78,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.End)); + return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.End); } set @@ -103,7 +103,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Left)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Left); } set @@ -116,7 +116,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Top)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Top); } set @@ -129,7 +129,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Right)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Right); } set @@ -142,7 +142,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Bottom)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Bottom); } set @@ -155,7 +155,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Start)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Start); } set @@ -168,7 +168,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.End)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.End); } set @@ -181,7 +181,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Horizontal)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Horizontal); } set @@ -194,7 +194,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Vertical)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Vertical); } set @@ -207,7 +207,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.All)); + return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.All); } set @@ -236,7 +236,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Left)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Left); } set @@ -249,7 +249,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Top)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Top); } set @@ -262,7 +262,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Right)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Right); } set @@ -275,7 +275,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Bottom)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Bottom); } set @@ -288,7 +288,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Start)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Start); } set @@ -301,7 +301,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.End)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.End); } set @@ -314,7 +314,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Horizontal)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Horizontal); } set @@ -327,7 +327,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Vertical)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Vertical); } set @@ -340,7 +340,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.All)); + return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.All); } set diff --git a/csharp/Facebook.Yoga/YogaNode.cs b/csharp/Facebook.Yoga/YogaNode.cs index b1f30b22..f681ec89 100644 --- a/csharp/Facebook.Yoga/YogaNode.cs +++ b/csharp/Facebook.Yoga/YogaNode.cs @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -271,7 +271,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetFlexBasis(_ygNode)); + return Native.YGNodeStyleGetFlexBasis(_ygNode); } set @@ -295,7 +295,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetWidth(_ygNode)); + return Native.YGNodeStyleGetWidth(_ygNode); } set @@ -319,7 +319,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetHeight(_ygNode)); + return Native.YGNodeStyleGetHeight(_ygNode); } set @@ -343,7 +343,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMaxWidth(_ygNode)); + return Native.YGNodeStyleGetMaxWidth(_ygNode); } set @@ -363,7 +363,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMaxHeight(_ygNode)); + return Native.YGNodeStyleGetMaxHeight(_ygNode); } set @@ -383,7 +383,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMinWidth(_ygNode)); + return Native.YGNodeStyleGetMinWidth(_ygNode); } set @@ -403,7 +403,7 @@ namespace Facebook.Yoga { get { - return YogaValue.MarshalValue(Native.YGNodeStyleGetMinHeight(_ygNode)); + return Native.YGNodeStyleGetMinHeight(_ygNode); } set diff --git a/csharp/Facebook.Yoga/YogaValue.cs b/csharp/Facebook.Yoga/YogaValue.cs index aca8882e..e249828d 100644 --- a/csharp/Facebook.Yoga/YogaValue.cs +++ b/csharp/Facebook.Yoga/YogaValue.cs @@ -91,17 +91,5 @@ namespace Facebook.Yoga { return Point(pointValue); } - -#if WINDOWS_UWP_ARM - internal static YogaValue MarshalValue(IntPtr ptr) - { - return Marshal.PtrToStructure(ptr); - } -#else - internal static YogaValue MarshalValue(YogaValue value) - { - return value; - } -#endif } } diff --git a/csharp/Yoga/Yoga.vcxproj b/csharp/Yoga/Yoga.vcxproj index 489492cb..5899a0db 100755 --- a/csharp/Yoga/Yoga.vcxproj +++ b/csharp/Yoga/Yoga.vcxproj @@ -38,39 +38,39 @@ DynamicLibrary true - v140 + v141 Unicode DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode DynamicLibrary false - v140 + v141 true Unicode DynamicLibrary true - v140 + v141 Unicode DynamicLibrary false - v140 + v141 true Unicode diff --git a/yoga/YGMacros.h b/yoga/YGMacros.h index 0aafdca3..eaaf179f 100644 --- a/yoga/YGMacros.h +++ b/yoga/YGMacros.h @@ -21,14 +21,6 @@ #define WIN_EXPORT #endif -#ifdef WINARMDLL -#define WIN_STRUCT(type) type * -#define WIN_STRUCT_REF(value) &value -#else -#define WIN_STRUCT(type) type -#define WIN_STRUCT_REF(value) value -#endif - #ifdef NS_ENUM // Cannot use NSInteger as NSInteger has a different size than int (which is the default type of a // enum). diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 10f27bf0..abd0dfa1 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -734,13 +734,13 @@ struct DimensionProp { } \ } \ \ - WIN_STRUCT(type) \ + type \ YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge) { \ YGValue value = node->getStyle().instanceName[edge]; \ if (value.unit == YGUnitUndefined || value.unit == YGUnitAuto) { \ value.value = YGUndefined; \ } \ - return WIN_STRUCT_REF(value); \ + return value; \ } #define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 237fc46b..d0d149e9 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -261,7 +261,7 @@ WIN_EXPORT void YGNodeStyleSetPositionPercent( const YGNodeRef node, const YGEdge edge, const float position); -WIN_EXPORT WIN_STRUCT(YGValue) +WIN_EXPORT YGValue YGNodeStyleGetPosition(const YGNodeRef node, const YGEdge edge); WIN_EXPORT void YGNodeStyleSetMargin( -- 2.50.1.windows.1