diff options
author | Ahmad Samir <a.samirh78@gmail.com> | 2023-12-14 18:48:17 +0200 |
---|---|---|
committer | Ahmad Samir <a.samirh78@gmail.com> | 2024-01-14 17:30:27 +0200 |
commit | 3d3eb7e402285b85b9f1296613a597453bcd18c9 (patch) | |
tree | d7e6e16de5fc2a4f9bb59a53261c97db7dcd4cb8 /src/corelib/io | |
parent | 1a3753fc78a55ed48aef8f3f7888ec4436f27eb4 (diff) |
QDirIterator: manage fs/file iterators with unique_ptr
Use std::stack/std::vector, since QList doesn't work with move only
types.
Change-Id: If0009c8127d56f85bb6b4b7bd40251cdc6b7950d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qdiriterator.cpp | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 5713f5c04d..e2b9b57374 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -72,21 +72,13 @@ #include <QtCore/private/qduplicatetracker_p.h> #include <memory> +#include <stack> +#include <vector> QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; -template <class Iterator> -class QDirIteratorPrivateIteratorStack : public QStack<Iterator *> -{ -public: - ~QDirIteratorPrivateIteratorStack() - { - qDeleteAll(*this); - } -}; - class QDirIteratorPrivate { public: @@ -109,9 +101,11 @@ public: QList<QRegularExpression> nameRegExps; #endif - QDirIteratorPrivateIteratorStack<QAbstractFileEngineIterator> fileEngineIterators; + using FEngineIteratorPtr = std::unique_ptr<QAbstractFileEngineIterator>; + std::stack<FEngineIteratorPtr, std::vector<FEngineIteratorPtr>> fileEngineIterators; #ifndef QT_NO_FILESYSTEMITERATOR - QDirIteratorPrivateIteratorStack<QFileSystemIterator> nativeIterators; + using FsIteratorPtr = std::unique_ptr<QFileSystemIterator>; + std::stack<FsIteratorPtr, std::vector<FsIteratorPtr>> nativeIterators; #endif QFileInfo currentFileInfo; @@ -170,15 +164,14 @@ void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo) QAbstractFileEngineIterator *it = engine->beginEntryList(filters, nameFilters); if (it) { it->setPath(path); - fileEngineIterators << it; + fileEngineIterators.emplace(FEngineIteratorPtr(it)); } else { // No iterator; no entry list. } } else { #ifndef QT_NO_FILESYSTEMITERATOR - QFileSystemIterator *it = new QFileSystemIterator(fileInfo.d_ptr->fileEntry, - filters, nameFilters, iteratorFlags); - nativeIterators << it; + nativeIterators.emplace(std::make_unique<QFileSystemIterator>( + fileInfo.d_ptr->fileEntry, filters, nameFilters, iteratorFlags)); #else qWarning("Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!"); #endif @@ -202,31 +195,46 @@ inline bool QDirIteratorPrivate::entryMatches(const QString & fileName, const QF /*! \internal + + Advances the internal iterator, either a QAbstractFileEngineIterator (e.g. + QResourceFileEngineIterator) or a QFileSystemIterator (which uses low-level + system methods, e.g. readdir() on Unix). + + An iterator stack is used for holding the iterators. + + A typical example of doing recursive iteration: + - while iterating directory A we find a sub-dir B + - an iterator for B is added to the iterator stack + - B's iterator is processed (the top() of the stack) first; then loop + goes back to processing A's iterator */ void QDirIteratorPrivate::advance() { + // Use get() in both code paths below because the iterator returned by top() + // may be invalidated due to reallocation when appending new iterators in + // pushDirectory(). + if (engine) { - while (!fileEngineIterators.isEmpty()) { + while (!fileEngineIterators.empty()) { // Find the next valid iterator that matches the filters. QAbstractFileEngineIterator *it; - while (it = fileEngineIterators.top(), it->hasNext()) { + while (it = fileEngineIterators.top().get(), it->hasNext()) { it->next(); if (entryMatches(it->currentFileName(), it->currentFileInfo())) return; } fileEngineIterators.pop(); - delete it; } } else { #ifndef QT_NO_FILESYSTEMITERATOR QFileSystemEntry nextEntry; QFileSystemMetaData nextMetaData; - while (!nativeIterators.isEmpty()) { + while (!nativeIterators.empty()) { // Find the next valid iterator that matches the filters. QFileSystemIterator *it; - while (it = nativeIterators.top(), it->advance(nextEntry, nextMetaData)) { + while (it = nativeIterators.top().get(), it->advance(nextEntry, nextMetaData)) { QFileInfo info(new QFileInfoPrivate(nextEntry, nextMetaData)); if (entryMatches(nextEntry.fileName(), info)) @@ -235,7 +243,6 @@ void QDirIteratorPrivate::advance() } nativeIterators.pop(); - delete it; } #endif } @@ -513,10 +520,10 @@ QFileInfo QDirIterator::nextFileInfo() bool QDirIterator::hasNext() const { if (d->engine) - return !d->fileEngineIterators.isEmpty(); + return !d->fileEngineIterators.empty(); else #ifndef QT_NO_FILESYSTEMITERATOR - return !d->nativeIterators.isEmpty(); + return !d->nativeIterators.empty(); #else return false; #endif |