diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 7b741acf..2fb4510c 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -5,6 +5,7 @@ * file in the root directory of this source tree. */ #include "YGNode.h" +#include #include #include "CompactValue.h" #include "Utils.h" @@ -12,6 +13,31 @@ using namespace facebook; using facebook::yoga::detail::CompactValue; +YGNode::YGNode(YGNode&& node) { + context_ = node.context_; + hasNewLayout_ = node.hasNewLayout_; + isReferenceBaseline_ = node.isReferenceBaseline_; + isDirty_ = node.isDirty_; + nodeType_ = node.nodeType_; + measureUsesContext_ = node.measureUsesContext_; + baselineUsesContext_ = node.baselineUsesContext_; + printUsesContext_ = node.printUsesContext_; + measure_ = node.measure_; + baseline_ = node.baseline_; + print_ = node.print_; + dirtied_ = node.dirtied_; + style_ = node.style_; + layout_ = node.layout_; + lineIndex_ = node.lineIndex_; + owner_ = node.owner_; + children_ = std::move(node.children_); + config_ = node.config_; + resolvedDimensions_ = node.resolvedDimensions_; + for (auto c : children_) { + c->setOwner(c); + } +} + void YGNode::print(void* printContext) { if (print_.noContext != nullptr) { if (printUsesContext_) { @@ -298,37 +324,6 @@ void YGNode::setPosition( trailing[crossAxis]); } -YGNode& YGNode::operator=(const YGNode& node) { - if (&node == this) { - return *this; - } - - for (auto child : children_) { - delete child; - } - - context_ = node.getContext(); - hasNewLayout_ = node.getHasNewLayout(); - nodeType_ = node.getNodeType(); - measureUsesContext_ = node.measureUsesContext_; - baselineUsesContext_ = node.baselineUsesContext_; - printUsesContext_ = node.printUsesContext_; - measure_ = node.measure_; - baseline_ = node.baseline_; - print_ = node.print_; - dirtied_ = node.getDirtied(); - style_ = node.style_; - layout_ = node.layout_; - lineIndex_ = node.getLineIndex(); - owner_ = node.getOwner(); - children_ = node.getChildren(); - config_ = node.getConfig(); - isDirty_ = node.isDirty(); - resolvedDimensions_ = node.getResolvedDimensions(); - - return *this; -} - YGValue YGNode::marginLeadingValue(const YGFlexDirection axis) const { if (YGFlexDirectionIsRow(axis) && !style_.margin[YGEdgeStart].isUndefined()) { return style_.margin[YGEdgeStart]; diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 42c99f00..b5ff98a5 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -55,6 +55,13 @@ private: void setMeasureFunc(decltype(measure_)); void setBaselineFunc(decltype(baseline_)); + // DANGER DANGER DANGER! + // If the the node assigned to has children, we'd either have to deallocate + // them (potentially incorrect) or ignore them (danger of leaks). Only ever + // use this after checking that there are no children. + // DO NOT CHANGE THE VISIBILITY OF THIS METHOD! + YGNode& operator=(YGNode&&) = default; + public: YGNode() : hasNewLayout_{true}, @@ -66,8 +73,16 @@ public: printUsesContext_{false} {} ~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree explicit YGNode(const YGConfigRef newConfig) : config_(newConfig){}; + + YGNode(YGNode&&); + + // Does not expose true value semantics, as children are not cloned eagerly. + // Should we remove this? YGNode(const YGNode& node) = default; - YGNode& operator=(const YGNode& node); + + // assignment means potential leaks of existing children, or alternatively + // freeing unowned memory, double free, or freeing stack memory. + YGNode& operator=(const YGNode&) = delete; // Getters void* getContext() const {