Skip to content

Commit 5783722

Browse files
committed
Simple implementation for directory_iterator as in STL is added.
1 parent f45da75 commit 5783722

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

filesystem/path.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <string>
1515
#include <vector>
1616
#include <stdexcept>
17+
#include <memory>
1718
#include <sstream>
1819
#include <cctype>
1920
#include <cstdlib>
@@ -25,6 +26,8 @@
2526
# include <ShlObj.h>
2627
#else
2728
# include <unistd.h>
29+
# include <dirent.h>
30+
# include <sys/types.h>
2831
#endif
2932
#include <sys/stat.h>
3033

@@ -403,6 +406,107 @@ class path {
403406
bool m_smb; // Unused, except for on Windows
404407
};
405408

409+
class directory_entry {
410+
public:
411+
directory_entry() = default;
412+
explicit directory_entry(const path& p) : p(p) {}
413+
filesystem::path path() const {
414+
return p;
415+
}
416+
417+
private:
418+
filesystem::path p;
419+
};
420+
421+
class directory_iterator {
422+
public:
423+
directory_iterator() = default;
424+
directory_iterator(const path& p) : p(p) {}
425+
directory_iterator(const directory_iterator& rhs) = default;
426+
directory_iterator(directory_iterator&& rhs) = default;
427+
~directory_iterator() = default;
428+
429+
directory_iterator begin() {
430+
#if defined(_WIN32)
431+
hFind = FindFirstFile((p / path("*")).str().c_str(), &findData);
432+
#else
433+
dir = std::shared_ptr<DIR>(opendir(p.str().c_str()), closedir);
434+
#endif
435+
return increment();
436+
}
437+
438+
directory_iterator end() const {
439+
return directory_iterator();
440+
}
441+
442+
bool operator==(const directory_iterator& rhs) const {
443+
return entry.path() == rhs.entry.path();
444+
}
445+
446+
bool operator!=(const directory_iterator& rhs) const {
447+
return entry.path() != rhs.entry.path();
448+
}
449+
450+
directory_entry operator*() const {
451+
return entry;
452+
}
453+
454+
directory_entry* operator->() {
455+
return &entry;
456+
}
457+
458+
directory_iterator& increment() {
459+
#if defined(_WIN32)
460+
if (hFind != NULL && hFind != INVALID_HANDLE_VALUE) {
461+
do {
462+
if (findData.cFileName[0] != '.') break;
463+
} while (FindNextFile(hFind, &findData));
464+
}
465+
466+
if (hFind != NULL && hFind != INVALID_HANDLE_VALUE) {
467+
entry = directory_entry(p / path(findData.cFileName));
468+
if (!FindNextFile(hFind, &findData)) {
469+
FindClose(hFind);
470+
hFind = NULL;
471+
}
472+
} else {
473+
entry = directory_entry();
474+
}
475+
#else
476+
dirent *ent = NULL;
477+
while ((ent = readdir(dir.get())) != NULL) {
478+
if (ent->d_name[0] != '.') break;
479+
}
480+
481+
if (ent)
482+
entry = directory_entry(p / path(ent->d_name));
483+
else
484+
entry = directory_entry();
485+
#endif
486+
return *this;
487+
}
488+
489+
directory_iterator& operator++() {
490+
return increment();
491+
}
492+
493+
directory_iterator operator++(int) {
494+
directory_iterator prev = *this;
495+
increment();
496+
return prev;
497+
}
498+
499+
private:
500+
path p;
501+
directory_entry entry;
502+
#if defined(_WIN32)
503+
HANDLE hFind = NULL;
504+
WIN32_FIND_DATA findData;
505+
#else
506+
std::shared_ptr<DIR> dir = nullptr;
507+
#endif
508+
};
509+
406510
inline bool create_directory(const path& p) {
407511
#if defined(_WIN32)
408512
return CreateDirectoryW(p.wstr().c_str(), NULL) != 0;

path_demo.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,16 @@ int main(int argc, char **argv) {
4444

4545
cout << "resolve(filesystem/path.h) = " << resolver().resolve("filesystem/path.h") << endl;
4646
cout << "resolve(nonexistant) = " << resolver().resolve("nonexistant") << endl;
47+
48+
cout << "filesystem:directory_entry = " << endl;
49+
for (const directory_entry& x : directory_iterator("filesystem")) {
50+
cout << " " << x.path() << endl;
51+
}
52+
53+
cout << "../filesystem:directory_entry = " << endl;
54+
for (const directory_entry& x : directory_iterator("../filesystem")) {
55+
cout << " " << x.path() << endl;
56+
}
57+
4758
return 0;
4859
}

0 commit comments

Comments
 (0)