A template for method forwarding?
Fawzi Mohamed
fmohamed at mac.com
Sat Dec 13 08:10:40 PST 2008
On 2008-12-13 15:29:19 +0100, Christopher Wright <dhasenan at gmail.com> said:
> Christian Kamm wrote:
>>> So looks like bad stringof is the culprit, once again.
>>
>> Why use stringof when you have an alias? This works for me in D1 - if you
>> discount default arguments and parameter storage classes (will templates
>> ever be able to touch these?).
>
> stringof sucks, but it's easy to work with.
>
> Your solution doesn't deal with method overloads. Passing in a method
> alias would work:
>
> template Forward(string classname, alias method)
> {
> mixin ("ReturnTypeOf!(method) " ~ method.stringof ~
> "(ParameterTupleOf!(Method) parameters) {
> return composed." ~ method.stringof ~ "(parameters);
> }");
> }
>
> Except method.stringof doesn't work, so you have to do it like this:
> template strof(alias method)
> {
> const strof = (&method).stringof[2..$];
> }
>
> template Forward(char[] classname, alias method)
> {
> mixin ("ReturnTypeOf!(method) " ~ strof!(method) ~
> "(ParameterTupleOf!(method) parameters) {
> return composed." ~ strof!(method) ~ "(parameters); }");
> }
In my testing framework I had first a version using stringof, and I was
able to pass the type or alias directly, this solved many issues.
I think that if doable passing types and aliases is indeed better than strings.
somewhat related to this topic I just found out that is(...
return/function/delegate) behave in a way that I did not expect, given
a method that returns an int and one that has an int argument (get/set)
one has:
typeof(&A.ret_int):int function()
typeof(&A.ret_int) U==return:int
typeof(&A.init.ret_int):int delegate()
typeof(&A.init.ret_int) T==return:int
typeof(&A.init.ret_int) T==delegate:int
typeof(&A.ret_void):void function(int a)
typeof(&A.ret_void) U==return:int
typeof(&A.init.ret_void):void delegate(int a)
typeof(&A.init.ret_void) T==return:int
typeof(&A.init.ret_void) T==delegate:int
for me it is ok as I wanted to have the type of the property
getter/setter, but it is not what I would have expected from the
documentation...
The prviosu running this program
{{{
import tango.io.Stdout;
class A{
int ret_int(){ return 3; }
void ret_void(int a){ }
}
void main(){
Stdout("typeof(&A.ret_int):")(typeof(&A.ret_int).stringof).newline;
static if(is(typeof(&A.ret_int) U==function))
Stdout("typeof(&A.ret_int) U==function:")(U.stringof).newline;
static if(is(typeof(&A.ret_int) U==return))
Stdout("typeof(&A.ret_int) U==return:")(U.stringof).newline;
Stdout("typeof(&A.init.ret_int):")(typeof(&A.init.ret_int).stringof).newline;
static if(is(typeof(&A.init.ret_int) T==return)){
Stdout("typeof(&A.init.ret_int) T==return:")(T.stringof).newline;
}
static if(is(typeof(&A.init.ret_int) T==function)){
Stdout("typeof(&A.init.ret_int) T==function:")(T.stringof).newline;
}
static if(is(typeof(&A.init.ret_int) T==delegate)){
Stdout("typeof(&A.init.ret_int) T==delegate:")(T.stringof).newline;
static if(is(T U==function))
Stdout("&A.init.ret_int delegate function:")(U.stringof).newline;
static if(is(T U==return))
Stdout("&A.init.ret_int delegate return:")(U.stringof).newline;
}
Stdout("typeof(&A.ret_void):")(typeof(&A.ret_void).stringof).newline;
static if(is(typeof(&A.ret_void) U==function))
Stdout("typeof(&A.ret_void) U==function:")(U.stringof).newline;
static if(is(typeof(&A.ret_void) U==return))
Stdout("typeof(&A.ret_void) U==return:")(U.stringof).newline;
Stdout("typeof(&A.init.ret_void):")(typeof(&A.init.ret_void).stringof).newline;
static if(is(typeof(&A.init.ret_void) T==return)){
Stdout("typeof(&A.init.ret_void) T==return:")(T.stringof).newline;
}
static if(is(typeof(&A.init.ret_void) T==delegate)){
Stdout("typeof(&A.init.ret_void) T==delegate:")(T.stringof).newline;
static if(is(T U==function))
Stdout("typeof(&A.init.ret_void) delegate
function:")(U.stringof).newline;
static if(is(T U==return))
Stdout("typeof(&A.init.ret_void) delegate
return:")(U.stringof).newline;
}
}
}}}
More information about the Digitalmars-d
mailing list