diff --git a/BUCK b/BUCK index 1087e7bb..58b6a659 100644 --- a/BUCK +++ b/BUCK @@ -14,9 +14,12 @@ GMOCK_OVERRIDE_FLAGS = [ COMPILER_FLAGS = LIBRARY_COMPILER_FLAGS + [ "-std=c++1y", + "-Wno-global-constructors", ] -TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + ["-std=c++1y"] +TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + [ + "-std=c++1y", +] cxx_library( name = "yoga", diff --git a/tests/YGPersistenceTest.cpp b/tests/YGPersistenceTest.cpp index 17334e89..53384060 100644 --- a/tests/YGPersistenceTest.cpp +++ b/tests/YGPersistenceTest.cpp @@ -235,7 +235,8 @@ TEST(YogaTest, cloning_and_freeing) { const YGNodeRef root2 = YGNodeClone(root); - // Freeing the original root should be safe as long as we don't free its children. + // Freeing the original root should be safe as long as we don't free its + // children. YGNodeFree(root); YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); diff --git a/tests/YGRoundingFunctionTest.cpp b/tests/YGRoundingFunctionTest.cpp index 94d5623b..00e22be6 100644 --- a/tests/YGRoundingFunctionTest.cpp +++ b/tests/YGRoundingFunctionTest.cpp @@ -8,7 +8,6 @@ */ #include - #include #include diff --git a/yoga/YGNodeList.cpp b/yoga/YGNodeList.cpp deleted file mode 100644 index e05ffa29..00000000 --- a/yoga/YGNodeList.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * 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. - */ - -#include - -#include "YGNodeList.h" - -struct YGNodeList { - uint32_t capacity; - uint32_t count; - YGNodeRef *items; -}; - -YGNodeListRef YGNodeListNew(const uint32_t initialCapacity) { - const YGNodeListRef list = - (const YGNodeListRef)malloc(sizeof(struct YGNodeList)); - YGAssert(list != nullptr, "Could not allocate memory for list"); - - list->capacity = initialCapacity; - list->count = 0; - list->items = (YGNodeRef*)malloc(sizeof(YGNodeRef) * list->capacity); - YGAssert(list->items != nullptr, "Could not allocate memory for items"); - - return list; -} - -void YGNodeListFree(const YGNodeListRef list) { - if (list) { - free(list->items); - free(list); - } -} - -uint32_t YGNodeListCount(const YGNodeListRef list) { - if (list) { - return list->count; - } - return 0; -} - -void YGNodeListAdd(YGNodeListRef *listp, const YGNodeRef node) { - if (!*listp) { - *listp = YGNodeListNew(4); - } - YGNodeListInsert(listp, node, (*listp)->count); -} - -void YGNodeListInsert(YGNodeListRef *listp, const YGNodeRef node, const uint32_t index) { - if (!*listp) { - *listp = YGNodeListNew(4); - } - YGNodeListRef list = *listp; - - if (list->count == list->capacity) { - list->capacity *= 2; - list->items = - (YGNodeRef*)realloc(list->items, sizeof(YGNodeRef) * list->capacity); - YGAssert(list->items != nullptr, "Could not extend allocation for items"); - } - - for (uint32_t i = list->count; i > index; i--) { - list->items[i] = list->items[i - 1]; - } - - list->count++; - list->items[index] = node; -} - -void YGNodeListReplace(YGNodeListRef list, const uint32_t index, const YGNodeRef newNode) { - list->items[index] = newNode; -} - -void YGNodeListRemoveAll(const YGNodeListRef list) { - for (uint32_t i = 0; i < list->count; i++) { - list->items[i] = nullptr; - } - list->count = 0; -} - -YGNodeRef YGNodeListRemove(const YGNodeListRef list, const uint32_t index) { - const YGNodeRef removed = list->items[index]; - list->items[index] = nullptr; - - for (uint32_t i = index; i < list->count - 1; i++) { - list->items[i] = list->items[i + 1]; - list->items[i + 1] = nullptr; - } - - list->count--; - return removed; -} - -YGNodeRef YGNodeListDelete(const YGNodeListRef list, const YGNodeRef node) { - for (uint32_t i = 0; i < list->count; i++) { - if (list->items[i] == node) { - return YGNodeListRemove(list, i); - } - } - - return nullptr; -} - -YGNodeRef YGNodeListGet(const YGNodeListRef list, const uint32_t index) { - if (YGNodeListCount(list) > 0) { - return list->items[index]; - } - - return nullptr; -} - -YGNodeListRef YGNodeListClone(const YGNodeListRef oldList) { - if (!oldList) { - return nullptr; - } - const uint32_t count = oldList->count; - if (count == 0) { - return nullptr; - } - const YGNodeListRef newList = YGNodeListNew(count); - memcpy(newList->items, oldList->items, sizeof(YGNodeRef) * count); - newList->count = count; - return newList; -} diff --git a/yoga/YGNodeList.h b/yoga/YGNodeList.h deleted file mode 100644 index 9c05eac0..00000000 --- a/yoga/YGNodeList.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * 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 "YGMacros.h" -#include "Yoga.h" - -YG_EXTERN_C_BEGIN - -typedef struct YGNodeList *YGNodeListRef; - -YGNodeListRef YGNodeListNew(const uint32_t initialCapacity); -void YGNodeListFree(const YGNodeListRef list); -uint32_t YGNodeListCount(const YGNodeListRef list); -void YGNodeListAdd(YGNodeListRef *listp, const YGNodeRef node); -void YGNodeListInsert(YGNodeListRef *listp, const YGNodeRef node, const uint32_t index); -void YGNodeListReplace(const YGNodeListRef list, const uint32_t index, const YGNodeRef newNode); -void YGNodeListRemoveAll(const YGNodeListRef list); -YGNodeRef YGNodeListRemove(const YGNodeListRef list, const uint32_t index); -YGNodeRef YGNodeListDelete(const YGNodeListRef list, const YGNodeRef node); -YGNodeRef YGNodeListGet(const YGNodeListRef list, const uint32_t index); -YGNodeListRef YGNodeListClone(YGNodeListRef list); - -YG_EXTERN_C_END diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 0d8ee75b..7ab673f4 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -205,7 +205,7 @@ void YGNodeToString( } appendFormatedString(str, ">"); - const uint32_t childCount = YGNodeListCount(node->children); + const uint32_t childCount = node->children.size(); if (options & YGPrintOptionsChildren && childCount > 0) { for (uint32_t i = 0; i < childCount; i++) { appendFormatedString(str, "\n"); diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index b85db0ea..568cd974 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -8,9 +8,12 @@ */ #pragma once -#include "YGNodeList.h" +#include + #include "Yoga.h" +using YGVector = std::vector; + YG_EXTERN_C_BEGIN WIN_EXPORT float YGRoundValueToPixelGrid(const float value, @@ -101,7 +104,7 @@ typedef struct YGNode { uint32_t lineIndex; YGNodeRef parent; - YGNodeListRef children; + YGVector children; struct YGNode* nextChild; @@ -205,7 +208,7 @@ static const YGNode gYGNodeDefaults = { .layout = gYGNodeLayoutDefaults, .lineIndex = 0, .parent = nullptr, - .children = nullptr, + .children = YGVector(), .nextChild = nullptr, .measure = nullptr, .baseline = nullptr, diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 63c446e8..fb0388d2 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -7,12 +7,11 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +#include "Yoga.h" #include - -#include "YGNodeList.h" +#include #include "YGNodePrint.h" #include "Yoga-internal.h" -#include "Yoga.h" #ifdef _MSC_VER #include @@ -66,6 +65,16 @@ static void YGNodeMarkDirtyInternal(const YGNodeRef node); static YGValue YGValueZero = {.value = 0, .unit = YGUnitPoint}; +static bool YGNodeListDelete(YGVector& list, const YGNodeRef node) { + std::vector::iterator p = + std::find(list.begin(), list.end(), node); + if (p != list.end()) { + list.erase(p); + return true; + } + return false; +} + #ifdef ANDROID #include static int YGAndroidLog(const YGConfigRef config, @@ -195,14 +204,11 @@ YGNodeRef YGNodeNew(void) { return YGNodeNewWithConfig(&gYGConfigDefaults); } -YGNodeRef YGNodeClone(const YGNodeRef oldNode) { - const YGNodeRef node = (const YGNodeRef)malloc(sizeof(YGNode)); +YGNodeRef YGNodeClone(YGNodeRef oldNode) { + YGNodeRef node = new YGNode(*oldNode); YGAssertWithConfig( oldNode->config, node != nullptr, "Could not allocate memory for node"); gNodeInstanceCount++; - - memcpy(node, oldNode, sizeof(YGNode)); - node->children = YGNodeListClone(oldNode->children); node->parent = nullptr; return node; } @@ -219,7 +225,8 @@ void YGNodeFree(const YGNodeRef node) { child->parent = nullptr; } - YGNodeListFree(node->children); + node->children.clear(); + node->children.shrink_to_fit(); free(node); gNodeInstanceCount--; } @@ -246,7 +253,8 @@ void YGNodeReset(const YGNodeRef node) { node->parent == nullptr, "Cannot reset a node still attached to a parent"); - YGNodeListFree(node->children); + node->children.clear(); + node->children.shrink_to_fit(); const YGConfigRef config = node->config; memcpy(node, &gYGNodeDefaults, sizeof(YGNode)); @@ -333,6 +341,7 @@ static void YGCloneChildrenIfNeeded(const YGNodeRef parent) { // This is an empty set. Nothing to clone. return; } + const YGNodeRef firstChild = YGNodeGetChild(parent, 0); if (firstChild->parent == parent) { // If the first child has this node as its parent, we assume that it is already unique. @@ -341,12 +350,12 @@ static void YGCloneChildrenIfNeeded(const YGNodeRef parent) { // We also assume that all its sibling are cloned as well. return; } + const YGNodeClonedFunc cloneNodeCallback = parent->config->cloneNodeCallback; - const YGNodeListRef children = parent->children; for (uint32_t i = 0; i < childCount; i++) { - const YGNodeRef oldChild = YGNodeListGet(children, i); + const YGNodeRef oldChild = parent->children[i]; const YGNodeRef newChild = YGNodeClone(oldChild); - YGNodeListReplace(children, i, newChild); + parent->children[i] = newChild; newChild->parent = parent; if (cloneNodeCallback) { cloneNodeCallback(oldChild, newChild, parent, i); @@ -365,8 +374,7 @@ void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32 "Cannot add child: Nodes with measure functions cannot have children."); YGCloneChildrenIfNeeded(node); - - YGNodeListInsert(&node->children, child, index); + node->children.insert(node->children.begin() + index, child); child->parent = node; YGNodeMarkDirtyInternal(node); } @@ -374,6 +382,7 @@ void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32 void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) { // This algorithm is a forked variant from YGCloneChildrenIfNeeded that excludes a child. const uint32_t childCount = YGNodeGetChildCount(parent); + if (childCount == 0) { // This is an empty set. Nothing to remove. return; @@ -382,7 +391,7 @@ void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) { if (firstChild->parent == parent) { // If the first child has this node as its parent, we assume that it is already unique. // We can now try to delete a child in this list. - if (YGNodeListDelete(parent->children, excludedChild) != nullptr) { + if (YGNodeListDelete(parent->children, excludedChild)) { excludedChild->layout = gYGNodeDefaults.layout; // layout is no longer valid excludedChild->parent = nullptr; YGNodeMarkDirtyInternal(parent); @@ -393,10 +402,9 @@ void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) { // We don't want to simply clone all children, because then the host will need to free // the clone of the child that was just deleted. const YGNodeClonedFunc cloneNodeCallback = parent->config->cloneNodeCallback; - const YGNodeListRef children = parent->children; uint32_t nextInsertIndex = 0; for (uint32_t i = 0; i < childCount; i++) { - const YGNodeRef oldChild = YGNodeListGet(children, i); + const YGNodeRef oldChild = parent->children[i]; if (excludedChild == oldChild) { // Ignore the deleted child. Don't reset its layout or parent since it is still valid // in the other parent. However, since this parent has now changed, we need to mark it @@ -405,7 +413,7 @@ void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) { continue; } const YGNodeRef newChild = YGNodeClone(oldChild); - YGNodeListReplace(children, nextInsertIndex, newChild); + parent->children[nextInsertIndex] = newChild; newChild->parent = parent; if (cloneNodeCallback) { cloneNodeCallback(oldChild, newChild, parent, nextInsertIndex); @@ -413,7 +421,7 @@ void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) { nextInsertIndex++; } while (nextInsertIndex < childCount) { - YGNodeListRemove(children, nextInsertIndex); + parent->children.erase(parent->children.begin() + nextInsertIndex); nextInsertIndex++; } } @@ -432,17 +440,21 @@ void YGNodeRemoveAllChildren(const YGNodeRef parent) { oldChild->layout = gYGNodeDefaults.layout; // layout is no longer valid oldChild->parent = nullptr; } - YGNodeListRemoveAll(parent->children); + parent->children.clear(); + parent->children.shrink_to_fit(); YGNodeMarkDirtyInternal(parent); return; } // Otherwise, we are not the owner of the child set. We don't have to do anything to clear it. - parent->children = nullptr; + parent->children = YGVector(); YGNodeMarkDirtyInternal(parent); } YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index) { - return YGNodeListGet(node->children, index); + if (index < node->children.size()) { + return node->children[index]; + } + return nullptr; } YGNodeRef YGNodeGetParent(const YGNodeRef node) { @@ -450,7 +462,7 @@ YGNodeRef YGNodeGetParent(const YGNodeRef node) { } uint32_t YGNodeGetChildCount(const YGNodeRef node) { - return YGNodeListCount(node->children); + return node->children.size(); } void YGNodeMarkDirty(const YGNodeRef node) { @@ -1687,7 +1699,7 @@ static void YGZeroOutLayoutRecursivly(const YGNodeRef node) { YGCloneChildrenIfNeeded(node); const uint32_t childCount = YGNodeGetChildCount(node); for (uint32_t i = 0; i < childCount; i++) { - const YGNodeRef child = YGNodeListGet(node->children, i); + const YGNodeRef child = node->children[i]; YGZeroOutLayoutRecursivly(child); } } @@ -1834,7 +1846,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, return; } - const uint32_t childCount = YGNodeListCount(node->children); + const uint32_t childCount = node->children.size(); if (childCount == 0) { YGNodeEmptyContainerSetMeasuredDimensions(node, availableWidth, @@ -1954,7 +1966,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM for (uint32_t i = 0; i < childCount; i++) { - const YGNodeRef child = YGNodeListGet(node->children, i); + const YGNodeRef child = node->children[i]; if (child->style.display == YGDisplayNone) { YGZeroOutLayoutRecursivly(child); child->hasNewLayout = true; @@ -2053,7 +2065,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Add items to the current line until it's full or we run out of items. for (uint32_t i = startOfLineIndex; i < childCount; i++, endOfLineIndex++) { - const YGNodeRef child = YGNodeListGet(node->children, i); + const YGNodeRef child = node->children[i]; if (child->style.display == YGDisplayNone) { continue; } @@ -2431,7 +2443,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, int numberOfAutoMarginsOnCurrentLine = 0; for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { - const YGNodeRef child = YGNodeListGet(node->children, i); + const YGNodeRef child = node->children[i]; if (child->style.positionType == YGPositionTypeRelative) { if (YGMarginLeadingValue(child, mainAxis)->unit == YGUnitAuto) { numberOfAutoMarginsOnCurrentLine++; @@ -2476,7 +2488,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, float crossDim = 0; for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { - const YGNodeRef child = YGNodeListGet(node->children, i); + const YGNodeRef child = node->children[i]; if (child->style.display == YGDisplayNone) { continue; } @@ -2561,7 +2573,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // We can skip child alignment if we're just measuring the container. if (performLayout) { for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { - const YGNodeRef child = YGNodeListGet(node->children, i); + const YGNodeRef child = node->children[i]; if (child->style.display == YGDisplayNone) { continue; } @@ -2726,7 +2738,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, float maxAscentForCurrentLine = 0; float maxDescentForCurrentLine = 0; for (ii = startIndex; ii < childCount; ii++) { - const YGNodeRef child = YGNodeListGet(node->children, ii); + const YGNodeRef child = node->children[ii]; if (child->style.display == YGDisplayNone) { continue; } @@ -2757,7 +2769,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (performLayout) { for (ii = startIndex; ii < endIndex; ii++) { - const YGNodeRef child = YGNodeListGet(node->children, ii); + const YGNodeRef child = node->children[ii]; if (child->style.display == YGDisplayNone) { continue; } @@ -2914,7 +2926,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Set trailing position if necessary. if (needsMainTrailingPos || needsCrossTrailingPos) { for (uint32_t i = 0; i < childCount; i++) { - const YGNodeRef child = YGNodeListGet(node->children, i); + const YGNodeRef child = node->children[i]; if (child->style.display == YGDisplayNone) { continue; } @@ -3359,7 +3371,7 @@ static void YGRoundToPixelGrid(const YGNodeRef node, (textRounding && !hasFractionalHeight)) - YGRoundValueToPixelGrid(absoluteNodeTop, pointScaleFactor, false, textRounding); - const uint32_t childCount = YGNodeListCount(node->children); + const uint32_t childCount = node->children.size(); for (uint32_t i = 0; i < childCount; i++) { YGRoundToPixelGrid(YGNodeGetChild(node, i), pointScaleFactor, absoluteNodeLeft, absoluteNodeTop); }