diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2020-03-31 22:14:40 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2020-06-06 13:43:04 +0200 |
commit | ccbf6ae0bbddff0001c7810934c8f15a8f50c2bb (patch) | |
tree | cb0557dc7fc7a3a0b34bffd5bd8fc907060e23b4 /src/corelib | |
parent | 1f80d1a5eb954856c29be75e77aad267b59ab3d0 (diff) |
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>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qdir.cpp | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index eaef3434b3..368ad648e0 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -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; } |