-
Notifications
You must be signed in to change notification settings - Fork 37
/
generator.cpp
79 lines (63 loc) · 2.4 KB
/
generator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "stackless_coroutine.hpp"
#include <assert.h>
#include <functional>
#include <iostream>
#include <experimental/filesystem>
struct variables_t {
std::string value;
std::experimental::filesystem::directory_iterator begin;
std::experimental::filesystem::directory_iterator end;
stackless_coroutine::generator<std::string> gen;
variables_t(const std::experimental::filesystem::path &path) : begin{path} {}
};
stackless_coroutine::generator<std::string>
get_directory_generator(const std::experimental::filesystem::path &p);
auto get_block() {
return stackless_coroutine::make_block(stackless_coroutine::make_while_true(
[](auto &context, auto &variables) {
if (variables.begin != variables.end)
return context.do_async_yield(variables.begin->path().string());
else
return context.do_async_break();
},
[](auto &context, auto &variables) {
variables.gen = get_directory_generator(variables.begin->path());
},
stackless_coroutine::make_while_true(
[](auto &context, auto &variables) {
auto iter = variables.gen.begin();
if (iter != variables.gen.end())
return context.do_async_yield(std::move(*iter));
else
return context.do_async_break();
},
[](auto &context, auto &variables) { ++variables.gen.begin(); }),
[](auto &context, auto &variables) { ++variables.begin; }
));
}
inline stackless_coroutine::generator<std::string>
get_directory_generator(const std::experimental::filesystem::path &p) {
return stackless_coroutine::make_generator<std::string, variables_t>(
get_block(), p);
}
#include <algorithm>
#include <vector>
int main() {
auto g = get_directory_generator(".");
{
auto g2 = get_directory_generator(".");
}
std::vector<std::string> vgen(g.begin(), g.end());
// Verify that we did the right thing by also checking using Filesystem TS
// recursive_directory_iterator
std::experimental::filesystem::recursive_directory_iterator begin{"."};
std::vector<std::string> vrdi;
for (auto &e : begin) {
vrdi.push_back(e.path().string());
}
std::sort(vgen.begin(), vgen.end());
std::sort(vrdi.begin(), vrdi.end());
std::cout << "Generator matches recursive_directory_iterator = "
<< std::boolalpha
<< std::equal(vgen.begin(), vgen.end(), vrdi.begin(), vrdi.end()) << "\n";
}