-
Notifications
You must be signed in to change notification settings - Fork 0
/
stl_generator.hpp
50 lines (42 loc) · 1.16 KB
/
stl_generator.hpp
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
#pragma once
// generator/continuation for C++
// author: Andrew Fedoniouk @ terrainformatica.com
// idea from: "coroutines in C" Simon Tatham,
// http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
// modified by Sen
// -- note: this is very evil usage of a C switch statement's ability to not break on a case, and being able to straddle across scopes.
// it's a perfect way to make portable generators (coroutines) though that compile on basically any C compiler
// -- as long as you don't yield across a switch statement (!)
/* example:
STL_GEN_START(myGenerator)
{
int i;
STL_GEN_EMIT_BEGIN(int)
for (i = 0; i < 100; i++)
STL_GEN_YIELD(100-i);
STL_GEN_EMIT_END()
};
int main()
{
myGenerator gen;
int v;
while (gen(v))
printf("%d\n", v);
}
*/
struct stl_generator
{
int _line;
stl_generator() :_line(0) {}
};
#define STL_GEN_START(NAME) struct NAME : public stl_generator
#define STL_GEN_EMIT_BEGIN(T) bool operator()(T& _rv) { \
switch (_line) { \
case 0:;
#define STL_GEN_EMIT_END() } _line = 0; return false; }
#define STL_GEN_YIELD(V) \
do { \
\
_line = __LINE__; \
_rv = (V); return true; case __LINE__:; \
} while (0)