QDir: port from QStringRef/split() to QStringView/tokenize()

Port away from random-access of the returned sequences. That's
neither necessary nor does it make the code more readable than
the alternative single-pass implementation used here.

As a drive-by, make applying NRVO more likely by re-using the
`result` variable for all returns after its declaration.

Change-Id: I2c3bbaefa6b6f08ebf0b90fb7be62e3c6243f19d
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Marc Mutz 2020-03-31 22:14:40 +02:00
parent 1f80d1a5eb
commit ccbf6ae0bb

View File

@ -867,29 +867,45 @@ QString QDir::relativeFilePath(const QString &fileName) const
#endif
QString result;
QVector<QStringRef> dirElts = dir.splitRef(QLatin1Char('/'), Qt::SkipEmptyParts);
QVector<QStringRef> fileElts = file.splitRef(QLatin1Char('/'), Qt::SkipEmptyParts);
const auto dirElts = dir.tokenize(QLatin1Char('/'), Qt::SkipEmptyParts);
const auto fileElts = file.tokenize(QLatin1Char('/'), Qt::SkipEmptyParts);
int i = 0;
while (i < dirElts.size() && i < fileElts.size() &&
const auto dend = dirElts.end();
const auto fend = fileElts.end();
auto dit = dirElts.begin();
auto fit = fileElts.begin();
const auto eq = [](QStringView lhs, QStringView rhs) {
return
#if defined(Q_OS_WIN)
dirElts.at(i).compare(fileElts.at(i), Qt::CaseInsensitive) == 0)
lhs.compare(rhs, Qt::CaseInsensitive) == 0;
#else
dirElts.at(i) == fileElts.at(i))
lhs == rhs;
#endif
++i;
};
for (int j = 0; j < dirElts.size() - i; ++j)
// std::ranges::mismatch
while (dit != dend && fit != fend && eq(*dit, *fit)) {
++dit;
++fit;
}
while (dit != dend) {
result += QLatin1String("../");
++dit;
}
for (int j = i; j < fileElts.size(); ++j) {
result += fileElts.at(j);
if (j < fileElts.size() - 1)
if (fit != fend) {
while (fit != fend) {
result += *fit++;
result += QLatin1Char('/');
}
result.chop(1);
}
if (result.isEmpty())
return QLatin1String(".");
result = QLatin1String(".");
return result;
}