From ccbf6ae0bbddff0001c7810934c8f15a8f50c2bb Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 31 Mar 2020 22:14:40 +0200 Subject: [PATCH] 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 --- src/corelib/io/qdir.cpp | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index eaef3434b3b..368ad648e08 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 dirElts = dir.splitRef(QLatin1Char('/'), Qt::SkipEmptyParts); - QVector 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; }