Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@RossBencina
Last active August 29, 2015 14:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RossBencina/299766c0783fda0eb993 to your computer and use it in GitHub Desktop.
Save RossBencina/299766c0783fda0eb993 to your computer and use it in GitHub Desktop.
C++ Coroutine Using Template
// Template-based Coroutine continuation idea by Ross Bencina <rossb@audiomulch.com> May 2014.
// see: https://groups.google.com/forum/#!topic/comp.lang.c++.moderated/ryhWI6cX3Ko
#include <iostream>
class MyCoroutine {
typedef MyCoroutine this_t;
typedef bool (this_t::*coroutine_fn_t) ();
coroutine_fn_t next_;
// This is a stackless co-routine. Any state that needs to be retained
// across yeild points needs to be stored at class scope.
// Coroutine state:
int i;
#define BEGIN_COROUTINE switch (PC) { case 0:;
#define YEILD(result) { next_ = &this_t::coroutine_fn<__LINE__>; return (result); case __LINE__:; }
#define END_COROUTINE {next_ = &this_t::coroutine_fn<__LINE__>; case __LINE__:;} }
template<int PC>
bool coroutine_fn() {
BEGIN_COROUTINE
std::cout << "before loop" << std::endl;
YEILD(true);
for(i=0; i < 5; ++i ){
std::cout << "in loop " << i << std::endl;
YEILD(true);
}
std::cout << "after loop A" << std::endl;
YEILD(true);
std::cout << "after loop B" << std::endl;
END_COROUTINE
return false; // Will repeat this value after termination.
}
public:
MyCoroutine()
: next_( &this_t::coroutine_fn<0> )
{
}
bool step() // returns true while continuing
{
return (this->*next_)();
}
};
int main(int argc, char* argv[])
{
std::cout << "*** Coroutine ***" << std::endl;
MyCoroutine coro;
while (coro.step()) /* nothing */ ;
std::cout << std::endl;
return 0;
}
@patxitron
Copy link

Very interesting implementation.

What license do you put it under?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment