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 <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2016-01-17 14:49:43 +01:00
parent 587c183608
commit 49388f3dfd
2 changed files with 20 additions and 27 deletions

View File

@ -2129,34 +2129,28 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
// 2) The floating or semi-floating anchors (items) that are those which // 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 // are connected to only one (or none) of the layout sides, thus are not
// influenced by the layout size. // influenced by the layout size.
QList<QList<QSimplexConstraint *> > parts = getGraphParts(orientation); const auto parts = getGraphParts(orientation);
// Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes // Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes
// of the "trunk" set of constraints and variables. // of the "trunk" set of constraints and variables.
// ### does trunk always exist? empty = trunk is the layout left->center->right // ### does trunk always exist? empty = trunk is the layout left->center->right
QList<QSimplexConstraint *> trunkConstraints = parts.at(0); const QList<AnchorData *> trunkVariables = getVariables(parts.trunkConstraints);
QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
// For minimum and maximum, use the path between the two layout sides as the // For minimum and maximum, use the path between the two layout sides as the
// objective function. // objective function.
AnchorVertex *v = layoutLastVertex[orientation]; AnchorVertex *v = layoutLastVertex[orientation];
GraphPath trunkPath = graphPaths[orientation].value(v); 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 // 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 // that is the size they will remain at, since they are not stretched by the
// layout. // layout.
// Skipping the first (trunk) if (feasible && !parts.nonTrunkConstraints.isEmpty()) {
for (int i = 1; i < parts.count(); ++i) { const QList<AnchorData *> partVariables = getVariables(parts.nonTrunkConstraints);
if (!feasible)
break;
QList<QSimplexConstraint *> partConstraints = parts.at(i);
QList<AnchorData *> partVariables = getVariables(partConstraints);
Q_ASSERT(!partVariables.isEmpty()); Q_ASSERT(!partVariables.isEmpty());
feasible &= calculateNonTrunk(partConstraints, partVariables); feasible = calculateNonTrunk(parts.nonTrunkConstraints, partVariables);
} }
// Propagate the new sizes down the simplified graph, ie. tell the // Propagate the new sizes down the simplified graph, ie. tell the
@ -2496,9 +2490,11 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
/*! /*!
\internal \internal
*/ */
QList< QList<QSimplexConstraint *> > QGraphicsAnchorLayoutPrivate::GraphParts
QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
{ {
GraphParts result;
Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]); Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]);
AnchorData *edgeL1 = 0; AnchorData *edgeL1 = 0;
@ -2513,9 +2509,8 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]); edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]);
} }
QList<QSimplexConstraint *> remainingConstraints = constraints[orientation] + itemCenterConstraints[orientation]; result.nonTrunkConstraints = constraints[orientation] + itemCenterConstraints[orientation];
QList<QSimplexConstraint *> trunkConstraints;
QSet<QSimplexVariable *> trunkVariables; QSet<QSimplexVariable *> trunkVariables;
trunkVariables += edgeL1; trunkVariables += edgeL1;
@ -2523,11 +2518,11 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
trunkVariables += edgeL2; trunkVariables += edgeL2;
bool dirty; bool dirty;
auto end = remainingConstraints.end(); auto end = result.nonTrunkConstraints.end();
do { do {
dirty = false; dirty = false;
auto isMatch = [&trunkConstraints, &trunkVariables](QSimplexConstraint *c) -> bool { auto isMatch = [&result, &trunkVariables](QSimplexConstraint *c) -> bool {
bool match = false; bool match = false;
// Check if this constraint have some overlap with current // 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 // If so, we add it to trunk, and erase it from the
// remaining constraints. // remaining constraints.
if (match) { if (match) {
trunkConstraints += c; result.trunkConstraints += c;
for (auto jt = c->variables.cbegin(), end = c->variables.cend(); jt != end; ++jt) for (auto jt = c->variables.cbegin(), end = c->variables.cend(); jt != end; ++jt)
trunkVariables.insert(jt.key()); trunkVariables.insert(jt.key());
return true; return true;
@ -2558,18 +2553,12 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
return false; 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; dirty = newEnd != end;
end = newEnd; end = newEnd;
} while (dirty); } while (dirty);
remainingConstraints.erase(end, remainingConstraints.end()); result.nonTrunkConstraints.erase(end, result.nonTrunkConstraints.end());
QList< QList<QSimplexConstraint *> > result;
result += trunkConstraints;
if (!remainingConstraints.isEmpty())
result += remainingConstraints; // non-trunk constraints
return result; return result;
} }

View File

@ -491,7 +491,11 @@ public:
void constraintsFromPaths(Orientation orientation); void constraintsFromPaths(Orientation orientation);
void updateAnchorSizes(Orientation orientation); void updateAnchorSizes(Orientation orientation);
QList<QSimplexConstraint *> constraintsFromSizeHints(const QList<AnchorData *> &anchors); QList<QSimplexConstraint *> constraintsFromSizeHints(const QList<AnchorData *> &anchors);
QList<QList<QSimplexConstraint *> > getGraphParts(Orientation orientation); struct GraphParts {
QList<QSimplexConstraint *> trunkConstraints;
QList<QSimplexConstraint *> nonTrunkConstraints;
};
GraphParts getGraphParts(Orientation orientation);
void identifyFloatItems(const QSet<AnchorData *> &visited, Orientation orientation); void identifyFloatItems(const QSet<AnchorData *> &visited, Orientation orientation);
void identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar); void identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar);