00001 #pragma once
00002
00003
00004
00005
00006
00007
00008
00009 template<typename T>
00010 struct _generator
00011 {
00012 T* _stack;
00013 int _line;
00014 _generator():_stack(0), _line(-1) {}
00015 void _push() { T* n = new T; *n = *static_cast<T*>(this); _stack = n; }
00016 bool _pop() { if(!_stack) return false; T* t = _stack; *static_cast<T*>(this) = *_stack; t->_stack = 0; delete t; return true; }
00017 ~_generator() { while(_pop()); }
00018 };
00019
00020 #define $generator(NAME) struct NAME : public _generator<NAME>
00021
00022 #define $emit(T) bool operator()(T& _rv) { \
00023 if(_line < 0) _line=0; \
00024 $START: switch(_line) { case 0:;
00025
00026 #define $stop } _line = 0; if(_pop()) goto $START; return false; }
00027
00028 #define $restart(WITH) { _push(); _stack->_line = __LINE__; _line=0; WITH; goto $START; case __LINE__:; }
00029
00030 #define $yield(V) \
00031 do {\
00032 _line=__LINE__;\
00033 _rv = (V); return true; case __LINE__:;\
00034 } while (0)