Created
January 18, 2018 05:04
-
-
Save sumomoneko/080181bb43f5340f75f9d12b85aa6012 to your computer and use it in GitHub Desktop.
stackless coroutine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// coroutine.hpp | |
// ~~~~~~~~~~~~~ | |
// | |
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) | |
// | |
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
// | |
#ifndef COROUTINE_HPP | |
#define COROUTINE_HPP | |
class coroutine | |
{ | |
public: | |
coroutine() : value_(0) {} | |
bool is_child() const { return value_ < 0; } | |
bool is_parent() const { return !is_child(); } | |
bool is_complete() const { return value_ == -1; } | |
private: | |
friend class coroutine_ref; | |
int value_; | |
}; | |
class coroutine_ref | |
{ | |
public: | |
coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {} | |
coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {} | |
~coroutine_ref() { if (!modified_) value_ = -1; } | |
operator int() const { return value_; } | |
int& operator=(int v) { modified_ = true; return value_ = v; } | |
private: | |
void operator=(const coroutine_ref&); | |
int& value_; | |
bool modified_; | |
}; | |
#define CORO_REENTER(c) \ | |
switch (coroutine_ref _coro_value = c) \ | |
case -1: if (_coro_value) \ | |
{ \ | |
goto terminate_coroutine; \ | |
terminate_coroutine: \ | |
_coro_value = -1; \ | |
goto bail_out_of_coroutine; \ | |
bail_out_of_coroutine: \ | |
break; \ | |
} \ | |
else case 0: | |
#define CORO_YIELD_IMPL(n) \ | |
for (_coro_value = (n);;) \ | |
if (_coro_value == 0) \ | |
{ \ | |
case (n): ; \ | |
break; \ | |
} \ | |
else \ | |
switch (_coro_value ? 0 : 1) \ | |
for (;;) \ | |
case -1: if (_coro_value) \ | |
goto terminate_coroutine; \ | |
else for (;;) \ | |
case 1: if (_coro_value) \ | |
goto bail_out_of_coroutine; \ | |
else case 0: | |
#define CORO_FORK_IMPL(n) \ | |
for (_coro_value = -(n);; _coro_value = (n)) \ | |
if (_coro_value == (n)) \ | |
{ \ | |
case -(n): ; \ | |
break; \ | |
} \ | |
else | |
#if defined(_MSC_VER) | |
# define CORO_YIELD CORO_YIELD_IMPL(__COUNTER__ + 1) | |
# define CORO_FORK CORO_FORK_IMPL(__COUNTER__ + 1) | |
#else // defined(_MSC_VER) | |
# define CORO_YIELD CORO_YIELD_IMPL(__LINE__) | |
# define CORO_FORK CORO_FORK_IMPL(__LINE__) | |
#endif // defined(_MSC_VER) | |
#endif // COROUTINE_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// yield.hpp | |
// ~~~~~~~~~ | |
// | |
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) | |
// | |
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
// | |
#include "coroutine.hpp" | |
#ifndef reenter | |
# define reenter(c) CORO_REENTER(c) | |
#endif | |
#ifndef yield | |
# define yield CORO_YIELD | |
#endif | |
#ifndef fork | |
# define fork CORO_FORK | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment