Utils: Use hidden friends for FilePath comparison, hash and debug

Change-Id: Ic458d64cecdc811bac6b1cfaeae344f1da1b8211
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2023-01-06 11:37:23 +01:00
parent 1874906ce1
commit fbb8d94e55
3 changed files with 64 additions and 80 deletions

View File

@@ -191,7 +191,7 @@ FilePath FilePath::currentWorkingPath()
bool FilePath::isRootPath() const bool FilePath::isRootPath() const
{ {
// FIXME: Make host-independent // FIXME: Make host-independent
return operator==(FilePath::fromString(QDir::rootPath())); return *this == FilePath::fromString(QDir::rootPath());
} }
QString FilePath::encodedHost() const QString FilePath::encodedHost() const
@@ -1003,43 +1003,6 @@ QVariant FilePath::toVariant() const
return toString(); return toString();
} }
bool FilePath::operator==(const FilePath &other) const
{
return pathView().compare(other.pathView(), caseSensitivity()) == 0
&& host() == other.host()
&& scheme() == other.scheme();
}
bool FilePath::operator!=(const FilePath &other) const
{
return !(*this == other);
}
bool FilePath::operator<(const FilePath &other) const
{
const int cmp = pathView().compare(other.pathView(), caseSensitivity());
if (cmp != 0)
return cmp < 0;
if (host() != other.host())
return host() < other.host();
return scheme() < other.scheme();
}
bool FilePath::operator<=(const FilePath &other) const
{
return !(other < *this);
}
bool FilePath::operator>(const FilePath &other) const
{
return other < *this;
}
bool FilePath::operator>=(const FilePath &other) const
{
return !(*this < other);
}
/*! /*!
\returns whether FilePath is a child of \a s \returns whether FilePath is a child of \a s
*/ */
@@ -1363,13 +1326,6 @@ FilePath FilePath::stringAppended(const QString &str) const
return FilePath::fromString(toString() + str); return FilePath::fromString(toString() + str);
} }
size_t FilePath::hash(uint seed) const
{
if (caseSensitivity() == Qt::CaseInsensitive)
return qHash(path().toCaseFolded(), seed);
return qHash(path(), seed);
}
QDateTime FilePath::lastModified() const QDateTime FilePath::lastModified() const
{ {
return fileAccess()->lastModified(*this); return fileAccess()->lastModified(*this);
@@ -1984,20 +1940,53 @@ DeviceFileHooks &DeviceFileHooks::instance()
return s_deviceHooks; return s_deviceHooks;
} }
} // namespace Utils QTCREATOR_UTILS_EXPORT bool operator==(const FilePath &first, const FilePath &second)
std::hash<Utils::FilePath>::result_type
std::hash<Utils::FilePath>::operator()(const std::hash<Utils::FilePath>::argument_type &fn) const
{ {
if (fn.caseSensitivity() == Qt::CaseInsensitive) return first.pathView().compare(second.pathView(), first.caseSensitivity()) == 0
return hash<string>()(fn.toString().toCaseFolded().toStdString()); && first.host() == second.host()
return hash<string>()(fn.toString().toStdString()); && first.scheme() == second.scheme();
} }
QT_BEGIN_NAMESPACE QTCREATOR_UTILS_EXPORT bool operator!=(const FilePath &first, const FilePath &second)
QDebug operator<<(QDebug dbg, const Utils::FilePath &c) {
return !(first == second);
}
QTCREATOR_UTILS_EXPORT bool operator<(const FilePath &first, const FilePath &second)
{
const int cmp = first.pathView().compare(second.pathView(), first.caseSensitivity());
if (cmp != 0)
return cmp < 0;
if (first.host() != second.host())
return first.host() < second.host();
return first.scheme() < second.scheme();
}
QTCREATOR_UTILS_EXPORT bool operator<=(const FilePath &first, const FilePath &second)
{
return !(second < first);
}
QTCREATOR_UTILS_EXPORT bool operator>(const FilePath &first, const FilePath &second)
{
return second < first;
}
QTCREATOR_UTILS_EXPORT bool operator>=(const FilePath &first, const FilePath &second)
{
return !(first < second);
}
QTCREATOR_UTILS_EXPORT size_t qHash(const FilePath &filePath, uint seed)
{
if (filePath.caseSensitivity() == Qt::CaseInsensitive)
return qHash(filePath.path().toCaseFolded(), seed);
return qHash(filePath.path(), seed);
}
QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug dbg, const FilePath &c)
{ {
return dbg << c.toString(); return dbg << c.toString();
} }
QT_END_NAMESPACE } // Utils

View File

@@ -132,12 +132,6 @@ public:
expected_str<qint64> writeFileContents(const QByteArray &data, qint64 offset = 0) const; expected_str<qint64> writeFileContents(const QByteArray &data, qint64 offset = 0) const;
FilePathInfo filePathInfo() const; FilePathInfo filePathInfo() const;
bool operator==(const FilePath &other) const;
bool operator!=(const FilePath &other) const;
bool operator<(const FilePath &other) const;
bool operator<=(const FilePath &other) const;
bool operator>(const FilePath &other) const;
bool operator>=(const FilePath &other) const;
[[nodiscard]] FilePath operator/(const QString &str) const; [[nodiscard]] FilePath operator/(const QString &str) const;
Qt::CaseSensitivity caseSensitivity() const; Qt::CaseSensitivity caseSensitivity() const;
@@ -147,8 +141,6 @@ public:
void clear(); void clear();
bool isEmpty() const; bool isEmpty() const;
size_t hash(uint seed) const;
[[nodiscard]] FilePath absoluteFilePath() const; [[nodiscard]] FilePath absoluteFilePath() const;
[[nodiscard]] FilePath absolutePath() const; [[nodiscard]] FilePath absolutePath() const;
[[nodiscard]] FilePath resolvePath(const FilePath &tail) const; [[nodiscard]] FilePath resolvePath(const FilePath &tail) const;
@@ -245,6 +237,20 @@ public:
expected_str<FilePath> localSource() const; expected_str<FilePath> localSource() const;
private: private:
// These are needed.
QTCREATOR_UTILS_EXPORT friend bool operator==(const FilePath &first, const FilePath &second);
QTCREATOR_UTILS_EXPORT friend bool operator!=(const FilePath &first, const FilePath &second);
QTCREATOR_UTILS_EXPORT friend bool operator<(const FilePath &first, const FilePath &second);
QTCREATOR_UTILS_EXPORT friend bool operator<=(const FilePath &first, const FilePath &second);
QTCREATOR_UTILS_EXPORT friend bool operator>(const FilePath &first, const FilePath &second);
QTCREATOR_UTILS_EXPORT friend bool operator>=(const FilePath &first, const FilePath &second);
QTCREATOR_UTILS_EXPORT friend size_t qHash(const FilePath &a, uint seed);
QTCREATOR_UTILS_EXPORT friend size_t qHash(const FilePath &a) { return qHash(a, 0); }
QTCREATOR_UTILS_EXPORT friend QDebug operator<<(QDebug dbg, const FilePath &c);
// Implementation details. May change.
friend class ::tst_fileutils; friend class ::tst_fileutils;
void setPath(QStringView path); void setPath(QStringView path);
void setFromString(QStringView filepath); void setFromString(QStringView filepath);
@@ -258,11 +264,6 @@ private:
unsigned short m_hostLen = 0; unsigned short m_hostLen = 0;
}; };
inline size_t qHash(const Utils::FilePath &a, uint seed = 0)
{
return a.hash(seed);
}
class QTCREATOR_UTILS_EXPORT DeviceFileHooks class QTCREATOR_UTILS_EXPORT DeviceFileHooks
{ {
public: public:
@@ -276,21 +277,15 @@ public:
std::function<expected_str<FilePath>(const FilePath &)> localSource; std::function<expected_str<FilePath>(const FilePath &)> localSource;
}; };
} // namespace Utils } // Utils
QT_BEGIN_NAMESPACE
QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug dbg, const Utils::FilePath &c);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(Utils::FilePath) Q_DECLARE_METATYPE(Utils::FilePath)
namespace std { namespace std {
template<>
struct QTCREATOR_UTILS_EXPORT hash<Utils::FilePath> template<> struct hash<Utils::FilePath>
{ {
using argument_type = Utils::FilePath; size_t operator()(const Utils::FilePath &fn) const { return qHash(fn); }
using result_type = size_t;
result_type operator()(const argument_type &fn) const;
}; };
} // namespace std } // std

View File

@@ -25,7 +25,7 @@ class CMakeFileInfo
{ {
public: public:
bool operator==(const CMakeFileInfo& other) const { return path == other.path; } bool operator==(const CMakeFileInfo& other) const { return path == other.path; }
friend auto qHash(const CMakeFileInfo &info, uint seed = 0) { return info.path.hash(seed); } friend size_t qHash(const CMakeFileInfo &info, uint seed = 0) { return qHash(info.path, seed); }
Utils::FilePath path; Utils::FilePath path;
bool isCMake = false; bool isCMake = false;