digitalmars.D - Forcing closures to come on the stack
- Mehrdad (57/57) Aug 07 2011 I just made something I thought I'd share.
- Simen Kjaeraas (6/30) Aug 08 2011 You could use the 'scope' keyword, no?
- %u (2/3) Aug 08 2011 From what I've heard it's being deprecated/removed -- although I'd be
- Jonathan M Davis (5/9) Aug 08 2011 scope on function parameters is sticking around as are scoped statements...
I just made something I thought I'd share.
It's great for those times when the compiler decides to randomly put a
closure on the heap.
The usage is pretty simple:
int x = 5;
auto adder5 = mixin(closure!x(q{(int a) { return a + x; }}));
assert(adder5(10) == 15);
It returns a callable struct whose body is the given string; the
template parameters are the variables under closure (in this case, x).
The generated code looks like (minus a little beautification on my part):
(delegate(ref int x) {
static struct State {
int* px;
property ref int x() { return *this.px; }
auto opCall(int a) { return a + x; }
}
State tmp;
tmp.px = &x;
return tmp;
})(x)
So when you assign it to something, that something becomes a struct with
opCall overloaded. You can then take the address of opCall on the
struct, and you get a delegate.
Thoughts?
----------------------------------------------
// Code:
string closure(States...)(string argsAndBody)
{
string stateArgs = null, stateVars = null, stateProps = null,
setStateVars = null;
alias staticMap!(StringOf, States) VarNames;
string varPtrs;
alias staticMap!(TypeStringOf, States) TypeNames;
foreach (i, varName; VarNames)
{
if (varPtrs != null) { varPtrs ~= ", "; }
if (stateArgs != null) { stateArgs ~= ", "; }
varPtrs ~= varName;
stateArgs ~= "ref " ~ TypeNames[i] ~ " " ~ varName;
stateVars ~= TypeNames[i] ~ "* ___p_" ~ varName ~ "; ";
stateProps ~= " property ref " ~ TypeNames[i] ~ " " ~ varName ~
"() { return *this.___p_" ~ varName ~ "; } ";
setStateVars ~= "___tmp.___p_" ~ varName ~ " = &" ~ varName ~ "; ";
}
return "("
~ "delegate(" ~ stateArgs ~ ") { "
~ "static struct State { "
~ stateVars ~ ""
~ stateProps ~ ""
~ "auto opCall" ~ argsAndBody
~ ""
~ "} "
~ "State ___tmp; "
~ setStateVars
~ "return ___tmp; "
~"})(" ~ varPtrs ~ ")";
}
Aug 07 2011
On Mon, 08 Aug 2011 04:51:19 +0200, Mehrdad <wfunction hotmail.com> wrote:
I just made something I thought I'd share.
It's great for those times when the compiler decides to randomly put a
closure on the heap.
The usage is pretty simple:
int x = 5;
auto adder5 = mixin(closure!x(q{(int a) { return a + x; }}));
assert(adder5(10) == 15);
It returns a callable struct whose body is the given string; the
template parameters are the variables under closure (in this case, x).
The generated code looks like (minus a little beautification on my part):
(delegate(ref int x) {
static struct State {
int* px;
property ref int x() { return *this.px; }
auto opCall(int a) { return a + x; }
}
State tmp;
tmp.px = &x;
return tmp;
})(x)
So when you assign it to something, that something becomes a struct with
opCall overloaded. You can then take the address of opCall on the
struct, and you get a delegate.
Thoughts?
You could use the 'scope' keyword, no?
Upon perusal of the documentation, it seems this is nowhere mentioned, and
a report may be in order.
--
Simen
Aug 08 2011
You could use the 'scope' keyword, no?From what I've heard it's being deprecated/removed -- although I'd be glad to hear otherwise.
Aug 08 2011
scope on function parameters is sticking around as are scoped statements. What's going around is scoped local variables which put a class on the stack. std.typecons.Scoped is replacing it. scoped delegates are sticking around though. - Jonathan M DavisYou could use the 'scope' keyword, no?From what I've heard it's being deprecated/removed -- although I'd be glad to hear otherwise.
Aug 08 2011








"Jonathan M Davis" <jmdavisProg gmx.com>