Skip to content

Commit 0d842b6

Browse files
committed
Merge branch 'pr2'
2 parents aed3776 + 5783722 commit 0d842b6

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

@@ -407,6 +410,107 @@ class path {
407410
bool m_smb; // Unused, except for on Windows
408411
};
409412

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

4848
cout << "resolve(filesystem/path.h) = " << resolver().resolve("filesystem/path.h") << endl;
4949
cout << "resolve(nonexistant) = " << resolver().resolve("nonexistant") << endl;
50+
51+
cout << "filesystem:directory_entry = " << endl;
52+
for (const directory_entry& x : directory_iterator("filesystem")) {
53+
cout << " " << x.path() << endl;
54+
}
55+
56+
cout << "../filesystem:directory_entry = " << endl;
57+
for (const directory_entry& x : directory_iterator("../filesystem")) {
58+
cout << " " << x.path() << endl;
59+
}
60+
5061
return 0;
5162
}

0 commit comments

Comments
 (0)