Thread overview
Possible?
Nov 13, 2009
Ary Borenszweig
Nov 13, 2009
Jacob Carlborg
Nov 13, 2009
Simen Kjaeraas
Nov 16, 2009
Ary Borenszweig
Nov 13, 2009
Bill Baxter
November 13, 2009
How can I know at compile time if all of the following are true for a given symbol s:
 1. s is a function
 2. the return type is a class that extends from class foo.Bar
 3. the function has three arguments and it is not variadic
 4. the first argument is an int
 5. the second argument is a struct
 6. the third argument is an associative array with char[] key and float value
November 13, 2009
On 11/13/09 22:11, Ary Borenszweig wrote:
> How can I know at compile time if all of the following are true for a
> given symbol s:
> 1. s is a function
> 2. the return type is a class that extends from class foo.Bar
> 3. the function has three arguments and it is not variadic
> 4. the first argument is an int
> 5. the second argument is a struct
> 6. the third argument is an associative array with char[] key and float
> value

static if (is(typeof({
/* test if your code compiles here */
})))
November 13, 2009
Ary Borenszweig <ary@esperanto.org.ar> wrote:

> How can I know at compile time if all of the following are true for a given symbol s:
>   1. s is a function
>   2. the return type is a class that extends from class foo.Bar
>   3. the function has three arguments and it is not variadic
>   4. the first argument is an int
>   5. the second argument is a struct
>   6. the third argument is an associative array with char[] key and float value


C f1( int a, S b, float[ char[] ] c ) { return null; }
D f2( int a, S b, float[ char[] ] c ) { return null; }
C f3( long a, S b, float[ char[] ] c ) { return null; }
C f4( int a, string b, float[ char[] ] c ) { return null; }
C f5( int a, S b, float[ const char[] ] c ) { return null; }
E f6( int a, string b, float[ char[] ] c ) { return null; }
E f7( int a, S b, float[ const char[] ]c ) { return null; }
C f8( T... )( int a, S b, float[ char[] ] c, T args ) { return null; }


template check( alias f ) {
	pragma( msg, (&f).stringof[2..$] );
	pragma( msg, "isFunction: " ~
		is( typeof( f ) == function ).stringof );
	pragma( msg, "isvariadic: " ~
		to!string( ParameterTypeTuple!( f ).length != 3 ) );
	pragma( msg, "  Derived from C: " ~
		is( ReturnType!( f ) : C ).stringof );
	pragma( msg, "  p1 == int: " ~
		is( Unqual!( ParameterTypeTuple!( f )[0] ) == int ).stringof );
	pragma( msg, "  p2 == struct: " ~
		is(ParameterTypeTuple!( f )[1] == struct ).stringof );
	pragma( msg, "  p2 == float[ char[] ]: " ~
		is(ParameterTypeTuple!( f )[2] == float[char[]] ).stringof );
}

mixin check!( f1 );
mixin check!( f2 );
mixin check!( f3 );
mixin check!( f4 );
mixin check!( f5 );
mixin check!( f6 );
mixin check!( f7 );
mixin check!( f8!( int ) );



-- 
Simen
November 13, 2009
On Fri, Nov 13, 2009 at 1:11 PM, Ary Borenszweig <ary@esperanto.org.ar> wrote:
> How can I know at compile time if all of the following are true for a given
> symbol s:
>  1. s is a function
>  2. the return type is a class that extends from class foo.Bar
>  3. the function has three arguments and it is not variadic
>  4. the first argument is an int
>  5. the second argument is a struct
>  6. the third argument is an associative array with char[] key and float
> value

For a question like that you should definitely specify whether you want D1 or D2.

Also do you really want to know if "s is a function"?  Or if "s is something which can be called like a function".  If the latter then you should test if call syntax compiles like Jacob suggested.  If not then I think you use "if(is(s == function))" like Simen said.

--bb
November 16, 2009
Simen Kjaeraas wrote:
> Ary Borenszweig <ary@esperanto.org.ar> wrote:
> 
>> How can I know at compile time if all of the following are true for a given symbol s:
>>   1. s is a function
>>   2. the return type is a class that extends from class foo.Bar
>>   3. the function has three arguments and it is not variadic
>>   4. the first argument is an int
>>   5. the second argument is a struct
>>   6. the third argument is an associative array with char[] key and float value
> 
> 
> C f1( int a, S b, float[ char[] ] c ) { return null; }
> D f2( int a, S b, float[ char[] ] c ) { return null; }
> C f3( long a, S b, float[ char[] ] c ) { return null; }
> C f4( int a, string b, float[ char[] ] c ) { return null; }
> C f5( int a, S b, float[ const char[] ] c ) { return null; }
> E f6( int a, string b, float[ char[] ] c ) { return null; }
> E f7( int a, S b, float[ const char[] ]c ) { return null; }
> C f8( T... )( int a, S b, float[ char[] ] c, T args ) { return null; }
> 
> 
> template check( alias f ) {
>     pragma( msg, (&f).stringof[2..$] );
>     pragma( msg, "isFunction: " ~
>         is( typeof( f ) == function ).stringof );
>     pragma( msg, "isvariadic: " ~
>         to!string( ParameterTypeTuple!( f ).length != 3 ) );
>     pragma( msg, "  Derived from C: " ~
>         is( ReturnType!( f ) : C ).stringof );
>     pragma( msg, "  p1 == int: " ~
>         is( Unqual!( ParameterTypeTuple!( f )[0] ) == int ).stringof );
>     pragma( msg, "  p2 == struct: " ~
>         is(ParameterTypeTuple!( f )[1] == struct ).stringof );
>     pragma( msg, "  p2 == float[ char[] ]: " ~
>         is(ParameterTypeTuple!( f )[2] == float[char[]] ).stringof );
> }
> 
> mixin check!( f1 );
> mixin check!( f2 );
> mixin check!( f3 );
> mixin check!( f4 );
> mixin check!( f5 );
> mixin check!( f6 );
> mixin check!( f7 );
> mixin check!( f8!( int ) );

Cool, thanks!

I just wanted to see how you deal in D with all these reflection stuff. I think it's very bad that you have to look at "is", "typeof", "std.traits" and "std.conv" to accomplish such things (very hard to find if you don't ask here) and also that "(&f).stringof[2..$]" is very misterious... It would be nice to have a uniform syntax for this.