Shouldn't __traits return Tuples?

Max Samukha samukha at voliacable.com.removethis
Tue Mar 31 02:00:59 PDT 2009


On Tue, 31 Mar 2009 10:55:22 +0200, Max Samukha
<samukha at voliacable.com.removethis> wrote:

>On Mon, 30 Mar 2009 22:04:57 +0200, Trass3r <mrmocool at gmx.de> wrote:
>
>>Max Samukha schrieb:
>>> It's possible to statically unroll the foreach's with a template
>>> generating a tuple of consequtive integers (not tested):
>>> 
>>> template Sequence(size_t count, size_t index = 0)
>>> {
>>>    static if (index < count)
>>>       alias Tuple!(index, Sequence!(count, index + 1)) Sequence;  
>>>    ...
>>> }
>>> 
>>> enum members = __traits (allMembers, Class);
>>> foreach (i; Sequence!(members.length))
>>> {
>>>      enum funcs = __traits (getVirtualFunctions, Class, members[i]);
>>>      foreach (j; Sequence!(funcs.length))
>>>      {
>>>          // do stuff
>>>      }
>>> }
>>
>>Well this is interesting. That code yields:
>>variable main.main._funcs_field_0 cannot be declared to be a function.
>>
>>
>>class Class
>>{
>>	int foo(int i)
>>	{
>>	return 1;
>>	}
>>}
>>[...]
>>
>>auto funcs = __traits(getVirtualFunctions, Class, members[i])(1);
>>
>>yields
>>Error: function expected before (), not tuple(foo) of type (int(int i))
>>
>>So it is a tuple although the docs tell us it's an array?
>>
>
>Yeah, __traits returns expressions of various types depending on the
>Id. In case of getVirtualFunctions, it's a tuple expression. You may
>want to look through traits.c in dmd sources to see what's going on.
>
>>
>>Strangely this doesn't work either:
>>
>>enum members = __traits (allMembers, Class);
>>foreach (i; Sequence!(members.length))
>>{
>>	
>>      foreach (j; __traits(getVirtualFunctions, Class, members[i]))
>>      {
>>		writefln(typeid(typeof(j)));
>>          // do stuff
>>      }
>>}
>>
>>Though it correctly gets foo() (leaving out typeof above yields 
>>"function main.Class.foo is used as a type") it doesn't compile when 
>>adding typeof:
>>
>>"variable main.main.i voids have no value"
>
>__traits is buggy. You could try to do what you want like this:
>
>template isFunction(C, string member)
>{
>    enum isFunction = is(typeof(mixin("C." ~ member)) == function);
>}
>
>void main()
>{
>    //SpinLock lock;
>
>    enum members = __traits(allMembers, Class);
>    foreach (i; Sequence!(members.length))
>    {
>        static if (isFunction!(Class, members[i]))
>        {
>            foreach (j; __traits(getVirtualFunctions, Class,
>members[i]))
>                writefln(members[i], ": ", typeid(typeof(j)));
>        }
>    }
>} 

SpinLock, you are out of place here.



More information about the Digitalmars-d mailing list