<div class="gmail_quote">On Sat, Sep 18, 2010 at 19:59, Juanjo Alvarez <span dir="ltr"><<a href="mailto:juanjux@gmail.com">juanjux@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
I wanted to ask how these would be done, because I can't find how to do it:<br>
<br>
1. Having the strings, defined at compile time, "MyClass" and "mymethod",<br>
how could I could I get to a delegate to MyClass.mymethod?<br></blockquote><div><br>You can insert them in a piece of code as a string, and then mix it in:<br><br>enum string code = "auto deleg = &" ~ className ~ "." ~ methodName ~ ";"; // auto deleg = &MyClass.mymethod;<br>
mixin(code); // created deleg, you're good to go.<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
2. Is there any way to apply a tuple to a function, expanding as arguments?<br>
<br>
Like:<br>
<br>
void f(int a, double b) {}<br>
auto tup = tuple(42, 3.14);<br>
f(<magic goes here with tup expanding as 42, 3.14>);<br></blockquote><div><br><br>Use the .field or .expand alias, exposed by Tuple!() to get a direct access to the internal expression tuple.<br><br>f(tup.expand); // cracks tup open<br>
<br>Recently, bug 2800 was corrected and you can also directly access a tuple's fields by indexing:<br><br>double d = tup[1]; // or simply: auto d = tup[1];<br><br>Before that, you had to do <br><br>double d = tup.field[1];<br>
<br>Recently, tuples also got a .length member. That's handy.<br>As for expanding tuples inside functions if you do that regularly, I suggest you use a function adaptor, like this:<br><br>template tuplify(alias fun) if (isCallable!fun)<br>
{<br> ReturnType!fun tuplify(Tuple!(ParameterTypeTuple!fun) tup)<br> {<br> return fun(tup.expand);<br> }<br>}<br><br>Usage:<br><br>alias tuplify!f tf;<br>tf(tup);<br><br>tf is a function, like any other. It accepts a Tuple!(int,double), cracks it open and pass it to f.<br>
<br>I don't know if you need some explanation on how it works? <br>Here it is anyway: tuplify is a template, a parameterized piece of code. tuplify takes only one template parameter, by alias. This means you give
it a name, any identifier in the current scope. You do not give it a
type. That's what allows you to write tuplify!f.<br><br>Here the result of the template instantation is a function with the same name 'tuplify'. When a template exposes only one identifier with its own name, it's as if the code inside the template got instantiated right there.<br>
So tuplify!f is a function. It could have been a function template, or any other D construct. I used "alias tuplify!f tf;" to be able to use tf as ... an alias (doh!) to tuplify!f. But I could also have used:<br>
<br>auto tf = &(tuplify!f); // tuplify!f is a function, tf is a pointer to this function.<br><br>You can treat tf as any other D function : pass it around, give it as a argument to other templates or functions, etc.<br>
<br>The template constraint if(isCallable!fun) means tuplify can only be instantiated on callables (function, delegates, pointer to functions, structs or classes with opCall defined, etc). Note that tuplify works on _all_ callables! After all, the only property I use in the code is that f can be called with (). <br>
<br>isCallable lives here:<br><a href="http://digitalmars.com/d/2.0/phobos/std_traits.html#isCallable">http://digitalmars.com/d/2.0/phobos/std_traits.html#isCallable</a><br><br>I use the ReturnType and ParameterTypeTuple templates to do a little compile-time introspection<br>
<br>You can find ReturnType and ParameterTypeTuple here:<br><a href="http://digitalmars.com/d/2.0/phobos/std_traits.html#ReturnType">http://digitalmars.com/d/2.0/phobos/std_traits.html#ReturnType</a><br><br>So the internally created function accepts a Tuple!(the types fun needs) as argument. I indicate to the compiler it will return what fun returns, but I could have used auto there instead.<br>
<br>Philippe<br></div></div>