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