From 49388f3dfde04a52cfc80cd628c2bc9af92a19e6 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 17 Jan 2016 14:49:43 +0100 Subject: QGraphicsAnchorLayout: return a struct instead of a QList ... of QLists. The returned list was only ever exactly of size one or two, and two only if a local QList in the getGraphParts() function was not empty. Instead of using a QList to return those QLists, use a small struct of two QLists. This way, we avoid copying, memory allocations, and the code becomes a lot clearer, because we can give the members of the struct meaningful names, instead of at(0) and at(1). As a consequence, at the call site, the loop over the result can now be collapsed into an if. Saves ~1200b in text size on optimized GCC 5.3 Linux AMD64 builds. Change-Id: I5c2a3b3be0edcc418b310551abca51c410aca7c8 Reviewed-by: Thiago Macieira --- .../graphicsview/qgraphicsanchorlayout_p.cpp | 41 ++++++++-------------- src/widgets/graphicsview/qgraphicsanchorlayout_p.h | 6 +++- 2 files changed, 20 insertions(+), 27 deletions(-) (limited to 'src/widgets/graphicsview') diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp index 95cdaaddc1..f0a525c1b6 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2129,34 +2129,28 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // 2) The floating or semi-floating anchors (items) that are those which // are connected to only one (or none) of the layout sides, thus are not // influenced by the layout size. - QList > parts = getGraphParts(orientation); + const auto parts = getGraphParts(orientation); // Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes // of the "trunk" set of constraints and variables. // ### does trunk always exist? empty = trunk is the layout left->center->right - QList trunkConstraints = parts.at(0); - QList trunkVariables = getVariables(trunkConstraints); + const QList trunkVariables = getVariables(parts.trunkConstraints); // For minimum and maximum, use the path between the two layout sides as the // objective function. AnchorVertex *v = layoutLastVertex[orientation]; GraphPath trunkPath = graphPaths[orientation].value(v); - bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables); + bool feasible = calculateTrunk(orientation, trunkPath, parts.trunkConstraints, trunkVariables); // For the other parts that not the trunk, solve only for the preferred size // that is the size they will remain at, since they are not stretched by the // layout. - // Skipping the first (trunk) - for (int i = 1; i < parts.count(); ++i) { - if (!feasible) - break; - - QList partConstraints = parts.at(i); - QList partVariables = getVariables(partConstraints); + if (feasible && !parts.nonTrunkConstraints.isEmpty()) { + const QList partVariables = getVariables(parts.nonTrunkConstraints); Q_ASSERT(!partVariables.isEmpty()); - feasible &= calculateNonTrunk(partConstraints, partVariables); + feasible = calculateNonTrunk(parts.nonTrunkConstraints, partVariables); } // Propagate the new sizes down the simplified graph, ie. tell the @@ -2496,9 +2490,11 @@ QList QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin /*! \internal */ -QList< QList > +QGraphicsAnchorLayoutPrivate::GraphParts QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) { + GraphParts result; + Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]); AnchorData *edgeL1 = 0; @@ -2513,9 +2509,8 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]); } - QList remainingConstraints = constraints[orientation] + itemCenterConstraints[orientation]; + result.nonTrunkConstraints = constraints[orientation] + itemCenterConstraints[orientation]; - QList trunkConstraints; QSet trunkVariables; trunkVariables += edgeL1; @@ -2523,11 +2518,11 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) trunkVariables += edgeL2; bool dirty; - auto end = remainingConstraints.end(); + auto end = result.nonTrunkConstraints.end(); do { dirty = false; - auto isMatch = [&trunkConstraints, &trunkVariables](QSimplexConstraint *c) -> bool { + auto isMatch = [&result, &trunkVariables](QSimplexConstraint *c) -> bool { bool match = false; // Check if this constraint have some overlap with current @@ -2542,7 +2537,7 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) // If so, we add it to trunk, and erase it from the // remaining constraints. if (match) { - trunkConstraints += c; + result.trunkConstraints += c; for (auto jt = c->variables.cbegin(), end = c->variables.cend(); jt != end; ++jt) trunkVariables.insert(jt.key()); return true; @@ -2558,18 +2553,12 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) return false; } }; - const auto newEnd = std::remove_if(remainingConstraints.begin(), end, isMatch); + const auto newEnd = std::remove_if(result.nonTrunkConstraints.begin(), end, isMatch); dirty = newEnd != end; end = newEnd; } while (dirty); - remainingConstraints.erase(end, remainingConstraints.end()); - - QList< QList > result; - result += trunkConstraints; - - if (!remainingConstraints.isEmpty()) - result += remainingConstraints; // non-trunk constraints + result.nonTrunkConstraints.erase(end, result.nonTrunkConstraints.end()); return result; } diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h index 4dba934626..c284e6ace3 100644 --- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h @@ -491,7 +491,11 @@ public: void constraintsFromPaths(Orientation orientation); void updateAnchorSizes(Orientation orientation); QList constraintsFromSizeHints(const QList &anchors); - QList > getGraphParts(Orientation orientation); + struct GraphParts { + QList trunkConstraints; + QList nonTrunkConstraints; + }; + GraphParts getGraphParts(Orientation orientation); void identifyFloatItems(const QSet &visited, Orientation orientation); void identifyNonFloatItems_helper(const AnchorData *ad, QSet *nonFloatingItemsIdentifiedSoFar); -- cgit v1.2.3