www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Function traits at compile time

reply Victor Nakoryakov <nail-mail mail.ru> writes:
Hi all,

Consider code:

class MyClass(StructT)
{
...
}

I know, that StructT has a function `foo` in it, but I don't know number 
of parameters and their types, of course. Does anybody knows a way to 
extract types to use them in `static if ( is(...) )` statements?


-- 
Victor (aka nail) Nakoryakov
nail-mail [at] mail.ru

Krasnoznamensk, Moscow, Russia
Jun 12 2006
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Victor Nakoryakov skrev:
 Hi all,
 
 Consider code:
 
 class MyClass(StructT)
 {
 ...
 }
 
 I know, that StructT has a function `foo` in it, but I don't know number 
 of parameters and their types, of course. Does anybody knows a way to 
 extract types to use them in `static if ( is(...) )` statements?

Hi, This is possible but a bit tricky. You can use the compiler IFTI support to extract this information. Make a template such as: template delegateInfo(Ret, T1, T2, T3) { Something!(Ret,T1,T2,T3) delegateInfo(Ret delegate(T1,T2,T3) x) {} } The template Something can then contain aliases for the different argument types. digitalmars.D/38553 has already implemented such templates for you (just change the function argument -> delegate and you should be able to do things like: class MyClass(StructT) { static if (funcInfo(&StructT.init.foo).numArgs == 1) { pragma(msg,"StructT.foo takes 1 argument"); } static if (is(typeof(funcInfo(&StructT.init.foo).Arg0Type) == int)) { pragma(msg,"First argument to StructT.foo is an int"); } } /Oskar
Jun 12 2006
parent Victor Nakoryakov <nail-mail mail.ru> writes:
Oskar Linde wrote:
 Victor Nakoryakov skrev:
 
 Hi all,

 Consider code:

 class MyClass(StructT)
 {
 ...
 }

 I know, that StructT has a function `foo` in it, but I don't know 
 number of parameters and their types, of course. Does anybody knows a 
 way to extract types to use them in `static if ( is(...) )` statements?

Hi, This is possible but a bit tricky. You can use the compiler IFTI support to extract this information. Make a template such as: template delegateInfo(Ret, T1, T2, T3) { Something!(Ret,T1,T2,T3) delegateInfo(Ret delegate(T1,T2,T3) x) {} } The template Something can then contain aliases for the different argument types. digitalmars.D/38553 has already implemented such templates for you (just change the function argument -> delegate and you should be able to do things like: class MyClass(StructT) { static if (funcInfo(&StructT.init.foo).numArgs == 1) { pragma(msg,"StructT.foo takes 1 argument"); } static if (is(typeof(funcInfo(&StructT.init.foo).Arg0Type) == int)) { pragma(msg,"First argument to StructT.foo is an int"); } } /Oskar

Oh, thanks a lot. Totaly forgot about IFTI! :) -- Victor (aka nail) Nakoryakov nail-mail [at] mail.ru Krasnoznamensk, Moscow, Russia
Jun 12 2006
prev sibling next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit


Victor Nakoryakov wrote:
 Hi all,

Hi.
 Consider code:
 
 class MyClass(StructT)
 {
 ....
 }
 
 I know, that StructT has a function `foo` in it, but I don't know number
 of parameters and their types, of course. Does anybody knows a way to
 extract types to use them in `static if ( is(...) )` statements?

Ok, this is ugly, and evil, evil hack, but it works. The python script that generated it is included if you need more and/or less arguments. Some examples: # NumberOfArgs!(&StructT.foo); // Number of arguments # ReturnType!(&StructT.foo); // Alias to return type # ArgType!(&Struct.foo, n); // Alias to type of 'n'th argument # // (counting from 1). Hope this helps :) -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 12 2006
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Daniel Keep skrev:
 Victor Nakoryakov wrote:
 Hi all,

Hi.
 Consider code:

 class MyClass(StructT)
 {
 ....
 }

 I know, that StructT has a function `foo` in it, but I don't know number
 of parameters and their types, of course. Does anybody knows a way to
 extract types to use them in `static if ( is(...) )` statements?

Ok, this is ugly, and evil, evil hack, but it works. The python script that generated it is included if you need more and/or less arguments.

Nice set of templates. Makes one wish D had variadic templates though. :)
 Some examples:
 
 # NumberOfArgs!(&StructT.foo); // Number of arguments
 # ReturnType!(&StructT.foo);   // Alias to return type
 # ArgType!(&Struct.foo, n);    // Alias to type of 'n'th argument
 #                              // (counting from 1).

I don't think those will work as typed. Unless I'm mistaken, you need typeof(&StructT.foo) instead of just &StructT.foo. And unless StructT.foo is static, you will need to add delegate (as different from function) overloads for ftype.d and use typeof(&StructT.init.foo). Apart from that, I must thank you for coming up with this inspired way of (ab)using the ifti support. I've found it much useful. Regards, Oskar
Jun 12 2006
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Oskar Linde wrote:
 Daniel Keep skrev:
 Victor Nakoryakov wrote:
 Hi all,

Hi.
 Consider code:

 class MyClass(StructT)
 {
 ....
 }

 I know, that StructT has a function `foo` in it, but I don't know number
 of parameters and their types, of course. Does anybody knows a way to
 extract types to use them in `static if ( is(...) )` statements?

Ok, this is ugly, and evil, evil hack, but it works. The python script that generated it is included if you need more and/or less arguments.

Nice set of templates. Makes one wish D had variadic templates though. :)

Oh-so-true.
 Some examples:

 # NumberOfArgs!(&StructT.foo); // Number of arguments
 # ReturnType!(&StructT.foo);   // Alias to return type
 # ArgType!(&Struct.foo, n);    // Alias to type of 'n'th argument
 #                              // (counting from 1).

I don't think those will work as typed. Unless I'm mistaken, you need typeof(&StructT.foo) instead of just &StructT.foo. And unless StructT.foo is static, you will need to add delegate (as different from function) overloads for ftype.d and use typeof(&StructT.init.foo).

You're absolutely right. I am an idiot. Forgive me, I haven't touched it in a while, and I've got cryptanalysis on the brain for my last exam. Stupid university... You DO indeed need to use ``Template!(typeof(&StructT.foo))``. However, I'm not sure how to fix the function pointer vs. delegate problem. AFAI understand the rules, you can't have two templates with the same arguments and use IFTI (hell, I don't think you can have two templates with the same arguments period). I suppose that if you picked apart the mangled name of the type, you could determine if it was a delegate or a function pointer, and then select the correct sub-template to extract the type. Whoo boy... this thing's getting huge. Guess I'll have to add a new template to my type traits library :P Walter, can't we just have variadic templates and/or compile-time reflection? I mean, that's gotta be easier then working with this unholy mess :P
 Apart from that, I must thank you for coming up with this inspired way
 of (ab)using the ifti support. I've found it much useful.

Oh yes, I was quite pleased with myself when the proverbial light bulb switched on. Rather like the time I worked out how to do pointers in VB6 ^_^. No reason just, y'know, because.
 Regards,
 
 Oskar

-- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 12 2006
prev sibling parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Oskar Linde wrote:
 Daniel Keep skrev:
 Victor Nakoryakov wrote:
 Hi all,

Hi.
 Consider code:

 class MyClass(StructT)
 {
 ....
 }

 I know, that StructT has a function `foo` in it, but I don't know number
 of parameters and their types, of course. Does anybody knows a way to
 extract types to use them in `static if ( is(...) )` statements?

Ok, this is ugly, and evil, evil hack, but it works. The python script that generated it is included if you need more and/or less arguments.

Nice set of templates. Makes one wish D had variadic templates though. :)
 Some examples:

 # NumberOfArgs!(&StructT.foo); // Number of arguments
 # ReturnType!(&StructT.foo);   // Alias to return type
 # ArgType!(&Struct.foo, n);    // Alias to type of 'n'th argument
 #                              // (counting from 1).

I don't think those will work as typed. Unless I'm mistaken, you need typeof(&StructT.foo) instead of just &StructT.foo. And unless StructT.foo is static, you will need to add delegate (as different from function) overloads for ftype.d and use typeof(&StructT.init.foo). Apart from that, I must thank you for coming up with this inspired way of (ab)using the ifti support. I've found it much useful.

"thank you for coming up with"... What do you mean? You already saw Tomasz S's code (news://news.digitalmars.com:119/e5kdls$bic$1 digitaldaemon.com) which does the same (in fact it's even a bit better since it is shorter due to that use of default argument values). Or am I missing something? (feeling sleep-deprived today :o ) -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 12 2006
next sibling parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Bruno Medeiros skrev:
 Oskar Linde wrote:
 Apart from that, I must thank you for coming up with this inspired way 
 of (ab)using the ifti support. I've found it much useful.

"thank you for coming up with"... What do you mean? You already saw Tomasz S's code (news://news.digitalmars.com:119/e5kdls$bic$1 digitaldaemon.com) which does the same (in fact it's even a bit better since it is shorter due to that use of default argument values). Or am I missing something? (feeling sleep-deprived today :o )

I am referring to the following post that predate the one you refer to: news://news.digitalmars.com:119/e5jrb7$2b0v$1 digitaldaemon.com /Oskar
Jun 12 2006
prev sibling parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Bruno Medeiros wrote:
 "thank you for coming up with"... What do you mean? You already saw 
 Tomasz S's code 
 (news://news.digitalmars.com:119/e5kdls$bic$1 digitaldaemon.com) which 
 does the same (in fact it's even a bit better since it is shorter due to 
 that use of default argument values). Or am I missing something? 
 (feeling sleep-deprived today :o )

It was Daniel who originally came up with the idea, I just posted a modification/improvement of it. At first I thought it would be impossibe to do it :)
Jun 12 2006
prev sibling parent Victor Nakoryakov <nail-mail mail.ru> writes:
Daniel Keep wrote:
 Victor Nakoryakov wrote:
 
Hi all,

Hi.
Consider code:

class MyClass(StructT)
{
....
}

I know, that StructT has a function `foo` in it, but I don't know number
of parameters and their types, of course. Does anybody knows a way to
extract types to use them in `static if ( is(...) )` statements?

Ok, this is ugly, and evil, evil hack, but it works. The python script that generated it is included if you need more and/or less arguments. Some examples: # NumberOfArgs!(&StructT.foo); // Number of arguments # ReturnType!(&StructT.foo); // Alias to return type # ArgType!(&Struct.foo, n); // Alias to type of 'n'th argument # // (counting from 1). Hope this helps :) -- Daniel

-- Victor (aka nail) Nakoryakov nail-mail [at] mail.ru Krasnoznamensk, Moscow, Russia
Jun 12 2006
prev sibling parent BCS <BCS pathlink.com> writes:
Victor Nakoryakov wrote:
 Hi all,
 
 Consider code:
 
 class MyClass(StructT)
 {
 ...
 }
 
 I know, that StructT has a function `foo` in it, but I don't know number 
 of parameters and their types, of course. Does anybody knows a way to 
 extract types to use them in `static if ( is(...) )` statements?
 
 

<code> import std.stdio; template isType(alias match, alias what) { static if(is(typeof(match) == typeof(what))) const bool isType = true; else const bool isType = false; } int foo(); int bar(int); void main() { writef(isType!(function int(){}, function int(){}),\n); } </code>
Jun 12 2006