Here is the object with the task and the task of destruction:
template<class F, class D>
struct coroutine {
F f;
D d;
template<class...Args>
std::result_of_t<F&(Args...)>
operator()(Args&&...args){
return f(std::forward<Args>(args)...);
}
~coroutine() {
d();
}
};
a factory for him:
template<class F, class D>
coroutine< std::decay_t<F>, std::decay_t<D> >
make_coroutine( F&& f, D&& d ) {
return {std::forward<F>(f), std::forward<D>(d)};
}
Some helper macros:
#define COROUTINE_STATE ED=(void*)0
#define START_COROUTINE if (ED) goto *ED
#define FINISH_COROUTINE return false
auto add(int a, int b, int * ret) {
timespec start;
clock_gettime(CLOCK_REALTIME, &start);
return make_coroutine([=]() mutable
{
timespec now;
while(true) {
clock_gettime(CLOCK_REALTIME, &now);
if (now.tv_sec - start.tv_sec > 1)
break;
return true;
}
*ret = a + b;
cout << "add " << a << " " << b << " equals: " << a + b << endl;
return false;
},
[]{
cout << "adder destroyed\n";
});
}
auto sum(int a, int b, int c, int * ret)
{
std::function<bool()> co;
int tmp = 0;
return make_coroutine([=,COROUTINE_STATE] () mutable
{
START_COROUTINE;
co = add(a, b, &tmp);
while(co())
YIELD();
co = add(tmp, c, ret);
while(co())
YIELD();
FINISH_COROUTINE;
},
[]{
std::cout << "winter is coming\n";
}
);
}
, - "", ED.
COROUTINE_STATE, ED. START_COROUTINE; , YIELD(), , FINISH_COROUTINE;, .
- . co, , co, , =.
, , "" FINISH_COROUTINE; somesuch. : , ED :
template<class F>
struct coroutine {
void** ED = nullptr;
F f;
template<class...Args>
std::result_of_t< F&(void**,Args...) >
operator()(Args&&...args){
return f(ED, std::forward<Args>(args)...);
}
~coroutine() {
void* end = 0;
f(&end);
}
};
template<class F>
coroutine<std::decay_t<F>>
make_coroutine(F&& f){return {std::forward<F>{f}};}
#define START_COROUTINE [=](void** ED)mutable{\
if (ED){if (*ED)goto *ED;\
else goto Cleanup;}
#define END_COROUTINE_BODY return false; Cleanup:
#define END_COROUTINE_CLEANUP }
#define END_COROUTINE END_COROUTINE_BODY; END_COROUTINE_CLEANUP
auto sum(int a, int b, int c, int * ret)
{
std::function<bool()> co = 0;
int tmp = 0;
return
START_COROUTINE
co = add(a, b, &tmp);
while(co())
YIELD();
co = add(tmp, c, ret);
while(co())
YIELD();
END_COROUTINE_BODY
std::cout << "winter is coming\n";
END_COROUTINE_CLEANUP;
}
- . ED , nullptr, , " ". , .
, std::function. , ( ), , .
, coroutine, , std::function<bool(). .