On 2008-12-13 15:29:19 +0100, Christopher Wright <dhase...@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;
  }
}
}}}

Reply via email to