#include <iostream>
#include <memory>
#define CONCAT2(x, y) x ## y
#define CONCAT(x, y) CONCAT2(x, y)
#ifdef _WIN32
#define GET_LABEL_PTR(p, label)\
{\
void* _theLabelPointer;\
__asm { mov [_theLabelPointer], offset label }\
p = _theLabelPointer;\
}
#define JUMP_TO_LABEL(p)\
{\
void* _theLabelPointer = p;\
__asm { jmp _theLabelPointer }\
}
#else // _WIN32
#define GET_LABEL_PTR(p, label) p = &&label;
#define JUMP_TO_LABEL(p) goto *p;
#endif // _WIN32
#define YIELD2(val,counter)\
{\
GET_LABEL_PTR(_p, CONCAT(YIELD,counter));\
i = (val);\
return i;\
CONCAT(YIELD,counter): ;\
}
#define YIELD(val) YIELD2(val,__COUNTER__)
#define RETURN { _ended = true; return i; }
#define DEF_ITER(ret_type, name, state_vars, code) \
struct name \
{\
state_vars;\
ret_type i;\
bool _ended; void* _p;\
name() : _ended(false), _p(0) {}\
bool ended() const { return _ended; }\
operator bool() { next(); return !_ended; }\
ret_type next()\
{\
if (_ended) { throw(0); return i; }\
if (_p)\
JUMP_TO_LABEL(_p);\
code;\
\
_ended = true;\
return i;\
}\
};
// Test iterators
DEF_ITER(int, get57, ,
YIELD(5);
YIELD(7);
RETURN;
YIELD(42); // Should not happen
)
DEF_ITER(int, fibos, int a;int b,
a = 1;
b = 1;
for (;;)
{
YIELD(a);
std::swap(a, b);
b += a;
}
)
DEF_ITER(int, range, int start;int end,
while (start < end)
{
YIELD(start);
++start;
}
)
DEF_ITER(int, range_recurse, int start; int end; std::unique_ptr<range_recurse> r,
r = NULL;
if (start >= end)
RETURN;
YIELD(start);
r.reset(new range_recurse);
r->start = start + 1;
r->end = end;
while (*r)
YIELD(r->i);
)
DEF_ITER(int, n_fibos, int count; fibos f; range r,
r.start = 0;
r.end = count;
while (r)
YIELD(f.next());
)
int main(int argc, char* argv[])
{
{
std::cout << "*** 5 fibos" << std::endl;
n_fibos s;
s.count = 5;
while (s)
std::cout << s.i << std::endl;
}
{
std::cout << "\n*** fibos < 20" << std::endl;
fibos s;
while (s && s.i < 20)
std::cout << s.i << std::endl;
}
{
std::cout << "\n*** 5 and 7" << std::endl;
get57 s;
while (s)
std::cout << s.i << std::endl;
}
{
std::cout << "\n*** 4..7" << std::endl;
range s; s.start = 4; s.end = 8;
while (s)
std::cout << s.i << std::endl;
}
{
std::cout << "\n*** 10..14" << std::endl;
range_recurse s; s.start = 10; s.end = 15;
while (s)
std::cout << s.i << std::endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKI2RlZmluZSBDT05DQVQyKHgsIHkpIHggIyMgeQojZGVmaW5lIENPTkNBVCh4LCB5KSBDT05DQVQyKHgsIHkpCgojaWZkZWYgX1dJTjMyCgojZGVmaW5lIEdFVF9MQUJFTF9QVFIocCwgbGFiZWwpXAogIHtcCiAgICB2b2lkKiBfdGhlTGFiZWxQb2ludGVyO1wKICAgIF9fYXNtIHsgbW92IFtfdGhlTGFiZWxQb2ludGVyXSwgb2Zmc2V0IGxhYmVsIH1cCiAgICBwID0gX3RoZUxhYmVsUG9pbnRlcjtcCiAgfQoKI2RlZmluZSBKVU1QX1RPX0xBQkVMKHApXAogIHtcCiAgICB2b2lkKiBfdGhlTGFiZWxQb2ludGVyID0gcDtcCiAgICBfX2FzbSB7IGptcCBfdGhlTGFiZWxQb2ludGVyIH1cCiAgfQoKI2Vsc2UgLy8gX1dJTjMyCgojZGVmaW5lIEdFVF9MQUJFTF9QVFIocCwgbGFiZWwpIHAgPSAmJmxhYmVsOwoKI2RlZmluZSBKVU1QX1RPX0xBQkVMKHApIGdvdG8gKnA7CgojZW5kaWYgLy8gX1dJTjMyCgojZGVmaW5lIFlJRUxEMih2YWwsY291bnRlcilcCiAge1wKICAgIEdFVF9MQUJFTF9QVFIoX3AsIENPTkNBVChZSUVMRCxjb3VudGVyKSk7XAogICAgaSA9ICh2YWwpO1wKICAgIHJldHVybiBpO1wKICAgIENPTkNBVChZSUVMRCxjb3VudGVyKTogO1wKICB9CgojZGVmaW5lIFlJRUxEKHZhbCkgWUlFTEQyKHZhbCxfX0NPVU5URVJfXykKCiNkZWZpbmUgUkVUVVJOIHsgX2VuZGVkID0gdHJ1ZTsgcmV0dXJuIGk7IH0KCiNkZWZpbmUgREVGX0lURVIocmV0X3R5cGUsIG5hbWUsIHN0YXRlX3ZhcnMsIGNvZGUpIFwKICBzdHJ1Y3QgbmFtZSBcCiAge1wKICAgIHN0YXRlX3ZhcnM7XAogICAgcmV0X3R5cGUgaTtcCiAgICBib29sIF9lbmRlZDsgdm9pZCogX3A7XAogICAgbmFtZSgpIDogX2VuZGVkKGZhbHNlKSwgX3AoMCkge31cCiAgICBib29sIGVuZGVkKCkgY29uc3QgeyByZXR1cm4gX2VuZGVkOyB9XAogICAgb3BlcmF0b3IgYm9vbCgpIHsgbmV4dCgpOyByZXR1cm4gIV9lbmRlZDsgfVwKICAgIHJldF90eXBlIG5leHQoKVwKICAgIHtcCiAgICAgIGlmIChfZW5kZWQpIHsgdGhyb3coMCk7IHJldHVybiBpOyB9XAogICAgICBpZiAoX3ApXAogICAgICAgIEpVTVBfVE9fTEFCRUwoX3ApO1wKICAgICAgY29kZTtcCiAgICAgIFwKICAgICAgIF9lbmRlZCA9IHRydWU7XAogICAgICAgcmV0dXJuIGk7XAogICAgfVwKICB9OwoKLy8gVGVzdCBpdGVyYXRvcnMKCkRFRl9JVEVSKGludCwgZ2V0NTcsICwKICBZSUVMRCg1KTsKICBZSUVMRCg3KTsKICBSRVRVUk47CiAgWUlFTEQoNDIpOyAvLyBTaG91bGQgbm90IGhhcHBlbgopCgpERUZfSVRFUihpbnQsIGZpYm9zLCAgaW50IGE7aW50IGIsCiAgYSA9IDE7CiAgYiA9IDE7CiAgZm9yICg7OykKICB7CiAgICBZSUVMRChhKTsKICAgIHN0ZDo6c3dhcChhLCBiKTsKICAgIGIgKz0gYTsKICB9CikKCkRFRl9JVEVSKGludCwgcmFuZ2UsIGludCBzdGFydDtpbnQgZW5kLAogIHdoaWxlIChzdGFydCA8IGVuZCkKICB7CiAgICBZSUVMRChzdGFydCk7CiAgICArK3N0YXJ0OwogIH0KKQoKREVGX0lURVIoaW50LCByYW5nZV9yZWN1cnNlLCBpbnQgc3RhcnQ7IGludCBlbmQ7IHN0ZDo6dW5pcXVlX3B0cjxyYW5nZV9yZWN1cnNlPiByLAogIHIgPSBOVUxMOwoKICBpZiAoc3RhcnQgPj0gZW5kKQogICAgUkVUVVJOOwoKICBZSUVMRChzdGFydCk7CiAgci5yZXNldChuZXcgcmFuZ2VfcmVjdXJzZSk7CiAgci0+c3RhcnQgPSBzdGFydCArIDE7CiAgci0+ZW5kID0gZW5kOwogIHdoaWxlICgqcikKICAgIFlJRUxEKHItPmkpOwopCgpERUZfSVRFUihpbnQsIG5fZmlib3MsIGludCBjb3VudDsgZmlib3MgZjsgcmFuZ2UgciwKICByLnN0YXJ0ID0gMDsKICByLmVuZCA9IGNvdW50OwogIHdoaWxlIChyKQogICAgWUlFTEQoZi5uZXh0KCkpOwopCgppbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKQp7CiAgewogICAgc3RkOjpjb3V0IDw8ICIqKiogNSBmaWJvcyIgPDwgc3RkOjplbmRsOwogICAgbl9maWJvcyBzOwogICAgcy5jb3VudCA9IDU7CiAgICB3aGlsZSAocykKICAgICAgc3RkOjpjb3V0IDw8IHMuaSA8PCBzdGQ6OmVuZGw7CiAgfQoKICB7CiAgICBzdGQ6OmNvdXQgPDwgIlxuKioqIGZpYm9zIDwgMjAiIDw8IHN0ZDo6ZW5kbDsKICAgIGZpYm9zIHM7CiAgICB3aGlsZSAocyAmJiBzLmkgPCAyMCkKICAgICAgc3RkOjpjb3V0IDw8IHMuaSA8PCBzdGQ6OmVuZGw7CiAgfQoKICB7CiAgICBzdGQ6OmNvdXQgPDwgIlxuKioqIDUgYW5kIDciIDw8IHN0ZDo6ZW5kbDsKICAgIGdldDU3IHM7CiAgICB3aGlsZSAocykKICAgICAgc3RkOjpjb3V0IDw8IHMuaSA8PCBzdGQ6OmVuZGw7CiAgfQoKICB7CiAgICBzdGQ6OmNvdXQgPDwgIlxuKioqIDQuLjciIDw8IHN0ZDo6ZW5kbDsKICAgIHJhbmdlIHM7IHMuc3RhcnQgPSA0OyBzLmVuZCA9IDg7CiAgICB3aGlsZSAocykKICAgICAgc3RkOjpjb3V0IDw8IHMuaSA8PCBzdGQ6OmVuZGw7CiAgfQoKICB7CiAgICBzdGQ6OmNvdXQgPDwgIlxuKioqIDEwLi4xNCIgPDwgc3RkOjplbmRsOwogICAgcmFuZ2VfcmVjdXJzZSBzOyBzLnN0YXJ0ID0gMTA7IHMuZW5kID0gMTU7CiAgICB3aGlsZSAocykKICAgICAgc3RkOjpjb3V0IDw8IHMuaSA8PCBzdGQ6OmVuZGw7CiAgfQogIHJldHVybiAwOwp9