summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qdir.cpp65
-rw-r--r--src/corelib/io/qdir.h44
-rw-r--r--src/corelib/io/qfile.cpp50
-rw-r--r--src/corelib/io/qfile.h107
-rw-r--r--src/corelib/io/qfileinfo.cpp81
-rw-r--r--src/corelib/io/qfileinfo.h38
-rw-r--r--tests/auto/corelib/io/qdir/qdir.pro2
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp41
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro1
-rw-r--r--tests/auto/corelib/io/qfile/test.pro2
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp51
-rw-r--r--tests/auto/corelib/io/qfileinfo/qfileinfo.pro3
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp93
13 files changed, 573 insertions, 5 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 5ce3fbcca8..20af40f973 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -585,8 +585,8 @@ QDir::QDir(const QString &path) : d_ptr(new QDirPrivate(path))
also sorts the names using \a sort.
The default \a nameFilter is an empty string, which excludes
- nothing; the default \a filters is \l AllEntries, which also means
- exclude nothing. The default \a sort is \l Name | \l IgnoreCase,
+ nothing; the default \a filters is \l AllEntries, which also
+ excludes nothing. The default \a sort is \l Name | \l IgnoreCase,
i.e. sort by name case-insensitively.
If \a path is an empty string, QDir uses "." (the current
@@ -2551,4 +2551,65 @@ QDebug operator<<(QDebug debug, const QDir &dir)
}
#endif // QT_NO_DEBUG_STREAM
+/*!
+ \fn QDir::QDir(const std::filesystem::path &path)
+ \since 6.0
+ Constructs a QDir pointing to the given directory \a path. If path
+ is empty the program's working directory, ("."), is used.
+
+ \sa currentPath()
+*/
+/*!
+ \fn QDir::QDir(const std::filesystem::path &path,
+ const QString &nameFilter,
+ SortFlags sort,
+ Filters filters)
+ \since 6.0
+
+ Constructs a QDir with path \a path, that filters its entries by
+ name using \a nameFilter and by attributes using \a filters. It
+ also sorts the names using \a sort.
+
+ The default \a nameFilter is an empty string, which excludes
+ nothing; the default \a filters is \l AllEntries, which also
+ excludes nothing. The default \a sort is \l Name | \l IgnoreCase,
+ i.e. sort by name case-insensitively.
+
+ If \a path is empty, QDir uses "." (the current
+ directory). If \a nameFilter is an empty string, QDir uses the
+ name filter "*" (all files).
+
+ Note that \a path need not exist.
+
+ \sa exists(), setPath(), setNameFilters(), setFilter(), setSorting()
+*/
+/*!
+ \fn void QDir::setPath(const std::filesystem::path &path)
+ \since 6.0
+ \overload
+*/
+/*!
+ \fn void QDir::addSearchPath(const QString &prefix, const std::filesystem::path &path)
+ \since 6.0
+ \overload
+*/
+/*!
+ \fn std::filesystem::path QDir::filesystemPath() const
+ \since 6.0
+ Returns path() as \c{std::filesystem::path}.
+ \sa path()
+*/
+/*!
+ \fn std::filesystem::path QDir::filesystemAbsolutePath() const
+ \since 6.0
+ Returns absolutePath() as \c{std::filesystem::path}.
+ \sa absolutePath()
+*/
+/*!
+ \fn std::filesystem::path QDir::filesystemCanonicalPath() const
+ \since 6.0
+ Returns canonicalPath() as \c{std::filesystem::path}.
+ \sa canonicalPath()
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index 45a40995f8..f0dda73ebb 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -41,13 +41,13 @@
#define QDIR_H
#include <QtCore/qstring.h>
+#include <QtCore/qfile.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qshareddata.h>
QT_BEGIN_NAMESPACE
-
class QDirIterator;
class QDirPrivate;
@@ -102,6 +102,22 @@ public:
QDir(const QString &path = QString());
QDir(const QString &path, const QString &nameFilter,
SortFlags sort = SortFlags(Name | IgnoreCase), Filters filter = AllEntries);
+#ifdef Q_CLANG_QDOC
+ QDir(const std::filesystem::path &path);
+ QDir(const std::filesystem::path &path, const QString &nameFilter,
+ SortFlags sort = SortFlags(Name | IgnoreCase), Filters filter = AllEntries);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ QDir(const T &path) : QDir(QtPrivate::fromFilesystemPath(path))
+ {
+ }
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ QDir(const T &path, const QString &nameFilter,
+ SortFlags sort = SortFlags(Name | IgnoreCase), Filters filter = AllEntries)
+ : QDir(QtPrivate::fromFilesystemPath(path), nameFilter, sort, filter)
+ {
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
~QDir();
QDir &operator=(const QDir &);
@@ -115,9 +131,26 @@ public:
{ qSwap(d_ptr, other.d_ptr); }
void setPath(const QString &path);
+#ifdef Q_CLANG_QDOC
+ void setPath(const std::filesystem::path &path);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ void setPath(const T &path)
+ {
+ setPath(QtPrivate::fromFilesystemPath(path));
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
QString path() const;
QString absolutePath() const;
QString canonicalPath() const;
+#if QT_CONFIG(cxx17_filesystem)
+ std::filesystem::path filesystemPath() const
+ { return QtPrivate::toFilesystemPath(path()); }
+ std::filesystem::path filesystemAbsolutePath() const
+ { return QtPrivate::toFilesystemPath(absolutePath()); }
+ std::filesystem::path filesystemCanonicalPath() const
+ { return QtPrivate::toFilesystemPath(canonicalPath()); }
+#endif // QT_CONFIG(cxx17_filesystem)
#if QT_DEPRECATED_SINCE(5, 13)
QT_DEPRECATED_X("Use QDir::addSearchPath() instead")
@@ -126,6 +159,15 @@ public:
static void setSearchPaths(const QString &prefix, const QStringList &searchPaths);
static void addSearchPath(const QString &prefix, const QString &path);
+#ifdef Q_CLANG_QDOC
+ static void addSearchPath(const QString &prefix, const std::filesystem::path &path);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ static void addSearchPath(const QString &prefix, const T &path)
+ {
+ addSearchPath(prefix, QtPrivate::fromFilesystemPath(path));
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
static QStringList searchPaths(const QString &prefix);
QString dirName() const;
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 0cdc5bd6d3..2a9c24bbd5 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -1210,6 +1210,56 @@ qint64 QFile::size() const
return QFileDevice::size(); // for now
}
+/*!
+ \fn QFile::QFile(const std::filesystem::path &name)
+ \since 6.0
+
+ Constructs a new file object to represent the file with the given \a name.
+*/
+/*!
+ \fn QFile::QFile(const std::filesystem::path &name, QObject *parent)
+ \since 6.0
+
+ Constructs a new file object with the given \a parent to represent the
+ file with the specified \a name.
+*/
+/*!
+ \fn std::filesystem::path QFile::filesystemFileName() const
+ \since 6.0
+ Returns fileName() as \c{std::filesystem::path}.
+*/
+/*!
+ \fn void QFile::setFileName(const std::filesystem::path &name)
+ \since 6.0
+ \overload
+*/
+/*!
+ \fn bool QFile::rename(const std::filesystem::path &newName)
+ \since 6.0
+ \overload
+*/
+/*!
+ \fn bool QFile::link(const std::filesystem::path &newName)
+ \since 6.0
+ \overload
+*/
+/*!
+ \fn bool QFile::copy(const std::filesystem::path &newName)
+ \since 6.0
+ \overload
+*/
+/*!
+ \fn QFile::Permissions QFile::permissions(const std::filesystem::path &filename)
+ \since 6.0
+ \overload
+*/
+/*!
+ \fn bool QFile::setPermissions(const std::filesystem::path &filename, Permissions permissionSpec)
+ \since 6.0
+ \overload
+*/
+
+
QT_END_NAMESPACE
#ifndef QT_NO_QOBJECT
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index 917fec4e1a..dab20b85a1 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -45,12 +45,44 @@
#include <QtCore/qstring.h>
#include <stdio.h>
+#if QT_CONFIG(cxx17_filesystem)
+#include <filesystem>
+#endif
+
#ifdef open
#error qfile.h must be included before any header file that defines open
#endif
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(cxx17_filesystem)
+namespace QtPrivate {
+inline QString fromFilesystemPath(const std::filesystem::path &path)
+{
+#ifdef Q_OS_WIN
+ return QString::fromStdWString(path.native());
+#else
+ return QString::fromStdString(path.native());
+#endif
+}
+
+inline std::filesystem::path toFilesystemPath(const QString &path)
+{
+#ifdef Q_OS_WIN
+ return std::filesystem::path(path.toStdU16String());
+#else
+ return std::filesystem::path(path.toStdString());
+#endif
+}
+
+// Both std::filesystem::path and QString (without QT_NO_CAST_FROM_ASCII) can be implicitly
+// constructed from string literals so we force the std::fs::path parameter to only
+// accept std::fs::path with no implicit conversions.
+template<typename T>
+using ForceFilesystemPath = typename std::enable_if_t<std::is_same_v<std::filesystem::path, T>, int>;
+}
+#endif // QT_CONFIG(cxx17_filesystem)
+
class QTemporaryFile;
class QFilePrivate;
@@ -64,14 +96,45 @@ class Q_CORE_EXPORT QFile : public QFileDevice
public:
QFile();
QFile(const QString &name);
+#ifdef Q_CLANG_QDOC
+ QFile(const std::filesystem::path &name);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ QFile(const T &name) : QFile(QtPrivate::fromFilesystemPath(name))
+ {
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
+
#ifndef QT_NO_QOBJECT
explicit QFile(QObject *parent);
QFile(const QString &name, QObject *parent);
-#endif
+
+#ifdef Q_CLANG_QDOC
+ QFile(const std::filesystem::path &path, QObject *parent);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ QFile(const T &path, QObject *parent) : QFile(QtPrivate::fromFilesystemPath(path), parent)
+ {
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
+#endif // !QT_NO_QOBJECT
~QFile();
QString fileName() const override;
+#if QT_CONFIG(cxx17_filesystem)
+ std::filesystem::path filesystemFileName() const
+ { return QtPrivate::toFilesystemPath(fileName()); }
+#endif
void setFileName(const QString &name);
+#ifdef Q_CLANG_QDOC
+ void setFileName(const std::filesystem::path &name);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ void setFileName(const T &name)
+ {
+ setFileName(QtPrivate::fromFilesystemPath(name));
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
#if defined(Q_OS_DARWIN)
// Mac always expects filenames in UTF-8... and decomposed...
@@ -129,12 +192,39 @@ public:
static bool moveToTrash(const QString &fileName, QString *pathInTrash = nullptr);
bool rename(const QString &newName);
+#ifdef Q_CLANG_QDOC
+ bool rename(const std::filesystem::path &newName);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ bool rename(const T &newName)
+ {
+ return rename(QtPrivate::fromFilesystemPath(newName));
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
static bool rename(const QString &oldName, const QString &newName);
bool link(const QString &newName);
+#ifdef Q_CLANG_QDOC
+ bool link(const std::filesystem::path &newName);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ bool link(const T &newName)
+ {
+ return link(QtPrivate::fromFilesystemPath(newName));
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
static bool link(const QString &oldname, const QString &newName);
bool copy(const QString &newName);
+#ifdef Q_CLANG_QDOC
+ bool copy(const std::filesystem::path &newName);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ bool copy(const T &newName)
+ {
+ return copy(QtPrivate::fromFilesystemPath(newName));
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
static bool copy(const QString &fileName, const QString &newName);
bool open(OpenMode flags) override;
@@ -150,6 +240,21 @@ public:
static Permissions permissions(const QString &filename);
bool setPermissions(Permissions permissionSpec) override;
static bool setPermissions(const QString &filename, Permissions permissionSpec);
+#ifdef Q_CLANG_QDOC
+ static Permissions permissions(const std::filesystem::path &filename);
+ static bool setPermissions(const std::filesystem::path &filename, Permissions permissionSpec);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ static Permissions permissions(const T &filename)
+ {
+ return permissions(QtPrivate::fromFilesystemPath(filename));
+ }
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ static bool setPermissions(const T &filename, Permissions permissionSpec)
+ {
+ return setPermissions(QtPrivate::fromFilesystemPath(filename), permissionSpec);
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
protected:
#ifdef QT_NO_QOBJECT
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 64b1557231..479532fc36 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -363,7 +363,7 @@ QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate(file.fileNa
/*!
Constructs a new QFileInfo that gives information about the given
- \a file in the directory \a dir.
+ \a file relative to the directory \a dir.
If \a dir has a relative path, the QFileInfo will also have a
relative path.
@@ -1576,4 +1576,83 @@ QDebug operator<<(QDebug dbg, const QFileInfo &fi)
}
#endif
+/*!
+ \fn QFileInfo::QFileInfo(const std::filesystem::path &file)
+ \since 6.0
+
+ Constructs a new QFileInfo that gives information about the given
+ \a file.
+
+ \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
+*/
+/*!
+ \fn QFileInfo::QFileInfo(const QDir &dir, const std::filesystem::path &file)
+ \since 6.0
+
+ Constructs a new QFileInfo that gives information about the given
+ \a file relative to the directory \a dir.
+
+ If \a dir has a relative path, the QFileInfo will also have a
+ relative path.
+
+ If \a file is an absolute path, then the directory specified
+ by \a dir will be disregarded.
+*/
+/*!
+ \fn void QFileInfo::setFile(const std::filesystem::path &file)
+ \since 6.0
+
+ Sets the file that the QFileInfo provides information about to \a
+ file.
+*/
+/*!
+ \fn std::filesystem::path QFileInfo::filesystemFilePath() const
+ \since 6.0
+
+ Returns filePath() as a \c{std::filesystem::path}.
+ \sa filePath()
+*/
+/*!
+ \fn std::filesystem::path QFileInfo::filesystemAbsoluteFilePath() const
+ \since 6.0
+
+ Returns absoluteFilePath() as a \c{std::filesystem::path}.
+ \sa absoluteFilePath()
+*/
+/*!
+ \fn std::filesystem::path QFileInfo::filesystemCanonicalFilePath() const
+ \since 6.0
+
+ Returns canonicalFilePath() as a \c{std::filesystem::path}.
+ \sa canonicalFilePath()
+*/
+/*!
+ \fn std::filesystem::path QFileInfo::filesystemPath() const
+ \since 6.0
+
+ Returns path() as a \c{std::filesystem::path}.
+ \sa path()
+*/
+/*!
+ \fn std::filesystem::path QFileInfo::filesystemAbsolutePath() const
+ \since 6.0
+
+ Returns absolutePath() as a \c{std::filesystem::path}.
+ \sa absolutePath()
+*/
+/*!
+ \fn std::filesystem::path QFileInfo::filesystemCanonicalPath() const
+ \since 6.0
+
+ Returns canonicalPath() as a \c{std::filesystem::path}.
+ \sa canonicalPath()
+*/
+/*!
+ \fn std::filesystem::path QFileInfo::filesystemSymLinkTarget() const
+ \since 6.0
+
+ Returns symLinkTarget() as a \c{std::filesystem::path}.
+ \sa symLinkTarget()
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index 7c7ff56ae4..2bed64eb1a 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -64,6 +64,18 @@ public:
QFileInfo(const QFile &file);
QFileInfo(const QDir &dir, const QString &file);
QFileInfo(const QFileInfo &fileinfo);
+#ifdef Q_CLANG_QDOC
+ QFileInfo(const std::filesystem::path &file);
+ QFileInfo(const QDir &dir, const std::filesystem::path &file);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ QFileInfo(const T &file) : QFileInfo(QtPrivate::fromFilesystemPath(file)) { }
+
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ QFileInfo(const QDir &dir, const T &file) : QFileInfo(dir, QtPrivate::fromFilesystemPath(file))
+ {
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
~QFileInfo();
QFileInfo &operator=(const QFileInfo &fileinfo);
@@ -78,6 +90,13 @@ public:
void setFile(const QString &file);
void setFile(const QFile &file);
void setFile(const QDir &dir, const QString &file);
+#ifdef Q_CLANG_QDOC
+ void setFile(const std::filesystem::path &file);
+#elif QT_CONFIG(cxx17_filesystem)
+ template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
+ void setFile(const T &file) { setFile(QtPrivate::fromFilesystemPath(file)); }
+#endif // QT_CONFIG(cxx17_filesystem)
+
bool exists() const;
static bool exists(const QString &file);
void refresh();
@@ -85,6 +104,14 @@ public:
QString filePath() const;
QString absoluteFilePath() const;
QString canonicalFilePath() const;
+#if QT_CONFIG(cxx17_filesystem)
+ std::filesystem::path filesystemFilePath() const
+ { return QtPrivate::toFilesystemPath(filePath()); }
+ std::filesystem::path filesystemAbsoluteFilePath() const
+ { return QtPrivate::toFilesystemPath(absoluteFilePath()); }
+ std::filesystem::path filesystemCanonicalFilePath() const
+ { return QtPrivate::toFilesystemPath(canonicalFilePath()); }
+#endif // QT_CONFIG(cxx17_filesystem)
QString fileName() const;
QString baseName() const;
QString completeBaseName() const;
@@ -95,6 +122,13 @@ public:
QString path() const;
QString absolutePath() const;
QString canonicalPath() const;
+#if QT_CONFIG(cxx17_filesystem)
+ std::filesystem::path filesystemPath() const { return QtPrivate::toFilesystemPath(path()); }
+ std::filesystem::path filesystemAbsolutePath() const
+ { return QtPrivate::toFilesystemPath(absolutePath()); }
+ std::filesystem::path filesystemCanonicalPath() const
+ { return QtPrivate::toFilesystemPath(canonicalPath()); }
+#endif // QT_CONFIG(cxx17_filesystem)
QDir dir() const;
QDir absoluteDir() const;
@@ -122,6 +156,10 @@ public:
QString readLink() const;
#endif
QString symLinkTarget() const;
+#if QT_CONFIG(cxx17_filesystem)
+ std::filesystem::path filesystemSymLinkTarget() const
+ { return QtPrivate::toFilesystemPath(symLinkTarget()); }
+#endif // QT_CONFIG(cxx17_filesystem)
QString owner() const;
uint ownerId() const;
diff --git a/tests/auto/corelib/io/qdir/qdir.pro b/tests/auto/corelib/io/qdir/qdir.pro
index a8b106e250..f6ff0d0421 100644
--- a/tests/auto/corelib/io/qdir/qdir.pro
+++ b/tests/auto/corelib/io/qdir/qdir.pro
@@ -12,3 +12,5 @@ contains(CONFIG, builtin_testdata): DEFINES += BUILTIN_TESTDATA
android:!android-embedded {
RESOURCES += android_testdata.qrc
}
+
+qtConfig(c++17): CONFIG += c++17
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 1162fb31e4..5462a63fab 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -216,6 +216,8 @@ private slots:
void emptyDir();
void nonEmptyDir();
+ void stdfilesystem();
+
private:
#ifdef BUILTIN_TESTDATA
QString m_dataPath;
@@ -2403,6 +2405,45 @@ void tst_QDir::nonEmptyDir()
QVERIFY(!dir.isEmpty());
}
+void tst_QDir::stdfilesystem()
+{
+#if QT_CONFIG(cxx17_filesystem)
+ namespace fs = std::filesystem;
+ fs::path path(".");
+ QDir dir(path);
+ QCOMPARE(dir, QDir(QStringLiteral(".")));
+
+ path = path / "testdir" / "dir";
+ dir.setPath(path);
+
+ QCOMPARE(dir, QDir(QStringLiteral("./testdir/dir")));
+
+ auto fsPath = dir.filesystemPath();
+ QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.path());
+ fsPath = dir.filesystemAbsolutePath();
+ QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.absolutePath());
+ fsPath = dir.filesystemCanonicalPath();
+ QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.canonicalPath());
+
+ QDir emptyPath(fs::path{});
+ QCOMPARE(emptyPath, QDir(QStringLiteral(".")));
+
+ {
+ // Test QDir ctor with filter and sorting reversed
+ QDir filteredDir(fs::path{"."} / "searchdir", "subdir*",
+ QDir::SortFlag::Reversed, QDir::Filter::Dirs);
+ QStringList entries = filteredDir.entryList();
+ QCOMPARE(entries, QStringList() << "subdir2" << "subdir1");
+ QCOMPARE(filteredDir.sorting(), QDir::SortFlag::Reversed);
+ QCOMPARE(filteredDir.filter(), QDir::Filter::Dirs);
+ QCOMPARE(filteredDir.nameFilters().length(), 1);
+ QCOMPARE(filteredDir.nameFilters().first(), "subdir*");
+ }
+#else
+ QSKIP("Not supported");
+#endif
+}
+
QTEST_MAIN(tst_QDir)
#include "tst_qdir.moc"
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro b/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
index 512da8939b..bc48a9fb39 100644
--- a/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
+++ b/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
@@ -2,3 +2,4 @@ SOURCES += main.cpp
QT = core
load(qt_test_helper)
+CONFIG += c++17
diff --git a/tests/auto/corelib/io/qfile/test.pro b/tests/auto/corelib/io/qfile/test.pro
index 7a2767bf3c..47b778bc33 100644
--- a/tests/auto/corelib/io/qfile/test.pro
+++ b/tests/auto/corelib/io/qfile/test.pro
@@ -24,3 +24,5 @@ TESTDATA += \
resources/file1.ext1
win32:!winrt: QMAKE_USE += ole32 uuid
+
+CONFIG += c++17
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 350bff0652..b8f0d29078 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -282,6 +282,8 @@ private slots:
void moveToTrash_data();
void moveToTrash();
+ void stdfilesystem();
+
private:
#ifdef BUILTIN_TESTDATA
QSharedPointer<QTemporaryDir> m_dataDir;
@@ -3812,5 +3814,54 @@ void tst_QFile::moveToTrash()
}
}
+void tst_QFile::stdfilesystem()
+{
+#if QT_CONFIG(cxx17_filesystem)
+ namespace fs = std::filesystem;
+ auto toFSPath = [](const QFile &file) { return fs::path(file.fileName().toStdU16String()); };
+ fs::path path { "./path" };
+ QFile file(path);
+ QCOMPARE(toFSPath(file), path);
+
+ QCOMPARE(path, file.filesystemFileName());
+
+ {
+ QFile parentedFile(path, this);
+ QCOMPARE(file.fileName(), parentedFile.fileName());
+ QCOMPARE(parentedFile.parent(), this);
+ }
+
+ path = path / "filename";
+ file.setFileName(path);
+ QCOMPARE(toFSPath(file), path);
+
+ path = "test-file";
+ file.setFileName(path);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.close();
+
+ path = "tile-fest";
+ QVERIFY(file.rename(path));
+ QVERIFY(fs::exists(path));
+ fs::path linkfile { "test-link" };
+ QVERIFY(file.link(linkfile));
+ QVERIFY(fs::exists(linkfile));
+
+ fs::path copyfile { "copy-file" };
+ QVERIFY(file.copy(copyfile));
+ QVERIFY(fs::exists(copyfile));
+
+ QFileDevice::Permissions p = QFile::permissions(path);
+ QVERIFY(p.testFlag(QFile::WriteUser) || p.testFlag(QFile::WriteOwner)); // some we know for sure
+ if (p.testFlag(QFile::ReadUser))
+ p.setFlag(QFile::ReadUser, false);
+ else if (p.testFlag(QFile::ReadOwner))
+ p.setFlag(QFile::ReadOwner, false);
+ QVERIFY(QFile::setPermissions(path, p));
+#else
+ QSKIP("Not supported");
+#endif
+}
+
QTEST_MAIN(tst_QFile)
#include "tst_qfile.moc"
diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
index d181d16a3e..af764f3679 100644
--- a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
+++ b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
@@ -6,3 +6,6 @@ RESOURCES += qfileinfo.qrc \
testdata.qrc
win32:!winrt: QMAKE_USE += advapi32 netapi32
+
+# for std::filesystem tests
+qtConfig(c++17): CONFIG += c++17
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index ebb9a0a44c..a1f9ca0b87 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -287,6 +287,8 @@ private slots:
void invalidState();
void nonExistingFile();
+ void stdfilesystem();
+
private:
const QString m_currentDir;
QString m_sourceFile;
@@ -2269,6 +2271,97 @@ void tst_QFileInfo::nonExistingFile()
stateCheck(info, dirname, filename);
}
+void tst_QFileInfo::stdfilesystem()
+{
+#if QT_CONFIG(cxx17_filesystem)
+
+ namespace fs = std::filesystem;
+
+ // Verify constructing with fs::path leads to valid objects
+ {
+ // We compare using absoluteFilePath since QFileInfo::operator== ends up using
+ // canonicalFilePath which evaluates to empty-string for non-existent paths causing
+ // these tests to always succeed.
+#define COMPARE_CONSTRUCTION(filepath) \
+ QCOMPARE(QFileInfo(fs::path(filepath)).absoluteFilePath(), \
+ QFileInfo(QString::fromLocal8Bit(filepath)).absoluteFilePath()); \
+ QCOMPARE(QFileInfo(base, fs::path(filepath)).absoluteFilePath(), \
+ QFileInfo(base, QString::fromLocal8Bit(filepath)).absoluteFilePath())
+
+ QDir base{ "../" }; // Used for the QFileInfo(QDir, <path>) ctor
+
+ COMPARE_CONSTRUCTION("./file");
+
+#ifdef Q_OS_WIN32
+ COMPARE_CONSTRUCTION("C:\\path\\to\\file.txt");
+ COMPARE_CONSTRUCTION("x:\\path/to\\file.txt");
+ COMPARE_CONSTRUCTION("D:/path/TO/file.txt");
+ COMPARE_CONSTRUCTION("//sharename/folder/file.txt");
+#endif
+ COMPARE_CONSTRUCTION("/path/TO/file.txt");
+ COMPARE_CONSTRUCTION("./path/TO/file.txt");
+ COMPARE_CONSTRUCTION("../file.txt");
+ COMPARE_CONSTRUCTION("./filæ.txt");
+
+#undef COMPARE_CONSTRUCTION
+ {
+ // One proper comparison with operator== for each ctor
+ QFile file(QStringLiteral("./filesystem_test_file.txt"));
+ if (!file.open(QFile::NewOnly))
+ QVERIFY(file.exists());
+ file.close();
+
+ QFileInfo pinfo{ fs::path{ "./filesystem_test_file.txt" } };
+ QFileInfo info{ QStringLiteral("./filesystem_test_file.txt") };
+ QCOMPARE(pinfo, info);
+ }
+
+ {
+ // And once more for QFileInfo(QDir, <path>)
+ const QString &subdir = QStringLiteral("./filesystem_test_dir/");
+ base = QDir(QStringLiteral("."));
+ if (!base.exists(subdir))
+ QVERIFY(base.mkdir(subdir));
+ base.cd(subdir);
+ QFile file{ base.filePath(QStringLiteral("./filesystem_test_file.txt")) };
+ if (!file.open(QFile::NewOnly))
+ QVERIFY(file.exists());
+ file.close();
+ QFileInfo pinfo{ base, fs::path{ "filesystem_test_file.txt" } };
+ QFileInfo info{ base, QStringLiteral("filesystem_test_file.txt") };
+ QCOMPARE(pinfo, info);
+ }
+ }
+
+ // Verify that functions returning path all point to the same place
+ {
+#define COMPARE_PATHS(actual, expected) \
+ QCOMPARE(QString::fromStdU16String(actual.u16string()), expected)
+
+ QFile file(QStringLiteral("./orig"));
+ if (!file.open(QFile::NewOnly))
+ QVERIFY(file.exists());
+ file.close();
+
+ QFileInfo info{ QStringLiteral("./orig") };
+ COMPARE_PATHS(info.filesystemPath(), info.path());
+ COMPARE_PATHS(info.filesystemAbsolutePath(), info.absolutePath());
+ COMPARE_PATHS(info.filesystemCanonicalPath(), info.canonicalPath());
+ COMPARE_PATHS(info.filesystemFilePath(), info.filePath());
+ COMPARE_PATHS(info.filesystemAbsoluteFilePath(), info.absoluteFilePath());
+ COMPARE_PATHS(info.filesystemCanonicalFilePath(), info.canonicalFilePath());
+
+ QVERIFY(file.link(QStringLiteral("./filesystem_test_symlink.lnk")));
+ info = QFileInfo{ "./filesystem_test_symlink.lnk" };
+
+ COMPARE_PATHS(info.filesystemSymLinkTarget(), info.symLinkTarget());
+#undef COMPARE_PATHS
+ }
+
+#else
+ QSKIP("Not supported");
+#endif
+}
QTEST_MAIN(tst_QFileInfo)
#include "tst_qfileinfo.moc"