I am playing with C++11 lambda/closure feature, trying to write a semi-coroutine (generator) function.
The following codes are my experiment. They works as expected (GCC 4.9/Linux).
I have read several on-line articles introducing C++ lambda/closure, now I understand the lambda function as a functor or function object.
My question is: where can I put the destructor code for closure object? how can I override the default destructor?
I need this function because, some coroutines may request certain system resources when I call the function constructing and returning the closure object (which represents a coroutine). But if the caller function decide to cancel / kill the operation, there should be a mechanism to inform the coroutine object to take some action. The ideal place to put code will be in the destructor, but I cannot find how.
Any suggestions?
#include <iostream>
#include <functional>
#include <time.h>
#define CONCAT01(a, b) a##b
#define CONCAT02(a, b) CONCAT01(a, b)
#define YIELD() \
do { \
CONCAT02(ENTRY, __LINE__): \
if (EP == && CONCAT02(ENTRY, __LINE__)) \
EP = 0; \
else \
{ \
EP = && CONCAT02(ENTRY, __LINE__); \
return true; \
} \
} while (0)
using namespace std;
typedef std::function<bool(void)> coroutine;
coroutine add(int a, int b, int * ret)
{
timespec start;
clock_gettime(CLOCK_REALTIME, &start);
return [=]() mutable -> bool
{
timespec now;
while(1) {
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;
};
}
coroutine sum(int a, int b, int c, int * ret)
{
void* EP = 0;
coroutine co = 0;
int tmp = 0;
return [=] () mutable -> bool
{
if (EP) goto *EP;
co = add(a, b, &tmp);
while(co())
YIELD();
co = add(tmp, c, ret);
while(co())
YIELD();
return false;
};
}
int main()
{
int ret;
coroutine c = sum(1, 2, 4, &ret);
while (c())
{
sleep(1);
cout << "wakeup" << endl;
}
cout << "final: " << ret << endl;
return 0;
}
Aucun commentaire:
Enregistrer un commentaire