The context
I am trying to implement an easy to use async/await
pattern in my C++ code, and I have a way of doing it that I find remarkably simple to use. However, since I am using macros, it also comes at a cost in terms of weakness against exotic code.
Here is the idea:
- We wrap the execution context in a class, whose members are the variables used by the
async
function. Inside the body of the
async
function I implement with macros a switch on a memberentrypoint
that I use to keep track where jump to when the execution of the function is resumed:switch(this->entrypoint) { // All the async code occurs here, like: await(this->foo = bar()); std :: cout << this->foo << std :: endl; await(this->foo2 = bar2()); std :: cout << this->foo2 << std :: endl; }
The
await(assignment)
macro actually defines something in the form:this->entrypoint = (some value x); return; case x:
Now, this is obviously less compact than a full-fledged async function
we could have, for example, in Javascript, but it is more than enough for my needs. Also this prevents nested switches (which I use very rarely) and you cannot define variables locally unless you wrap them somehow in a { /*..*/ }
. But I get a super compact way of doing asynchronous operations with a synchronous style.
Remark: The downsides and weaknesses of this strategy are quite clear to me, this is not the point of my question, I just added this to help understand what I need.
The question
The above compiles and runs nicely. However, I am having a serious problem: in the await
macro, I need to generate some unique value x
to use in the case
statement. So far, I am doing it using __LINE__
, which works nicely and prevents collisions for most practical purposes. What happens, however, when you write two await
statements on the same line?
So I wonder: is there a better way than using __LINE__
to uniquely identify a call to a macro, so that whenever I call the same macro from two distinct places in my code I get different values expanded?