Jump to page: 1 2 3
Thread overview
Shouldn't __traits return Tuples?
Mar 30, 2009
Trass3r
Mar 30, 2009
Max Samukha
Mar 30, 2009
Trass3r
Mar 31, 2009
Max Samukha
Mar 31, 2009
Max Samukha
Mar 31, 2009
Trass3r
Mar 31, 2009
Max Samukha
Mar 31, 2009
Trass3r
Mar 31, 2009
Christopher Wright
Mar 31, 2009
Trass3r
Apr 01, 2009
Christopher Wright
Apr 01, 2009
Don
Apr 01, 2009
Trass3r
Apr 01, 2009
Don
Apr 01, 2009
Trass3r
Apr 01, 2009
Max Samukha
Apr 01, 2009
Trass3r
Apr 01, 2009
Max Samukha
Apr 01, 2009
Trass3r
Apr 02, 2009
Max Samukha
Apr 01, 2009
Trass3r
Apr 02, 2009
Trass3r
Apr 02, 2009
Daniel Keep
Apr 02, 2009
Don
Apr 03, 2009
Gide Nwawudu
March 30, 2009
Shouldn't __traits return Tuples instead of arrays (esp. allMembers) to allow sophisticated compile time reflection?
Currently it seems impossible to do something along the lines of

foreach (member; __traits (allMembers, Class))
{
    foreach (overload; __traits (getVirtualFunctions, Class, member))
    {
        // do stuff
    }
}

Maybe it would be possible with Tuples using template recursion.



Also the following doesn't work with dmd, returns 0 for all members:

Base base = new Base;
auto members = __traits(allMembers, typeof(base));
foreach(m; members)
    writefln(base.classinfo.getMembers(m).length);
March 30, 2009
On Mon, 30 Mar 2009 15:06:09 +0200, Trass3r <mrmocool@gmx.de> wrote:

>Shouldn't __traits return Tuples instead of arrays (esp. allMembers) to
>allow sophisticated compile time reflection?
>Currently it seems impossible to do something along the lines of
>
>foreach (member; __traits (allMembers, Class))
>{
>     foreach (overload; __traits (getVirtualFunctions, Class, member))
>     {
>         // do stuff
>     }
>}

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
     }
}

I'm not sure __traits should return tuples because arrays can be used with CTFE without generating an extra symbol, meaning less code bloat.

>
>Maybe it would be possible with Tuples using template recursion.
>
>
>
>Also the following doesn't work with dmd, returns 0 for all members:
>
>Base base = new Base;
>auto members = __traits(allMembers, typeof(base));
>foreach(m; members)
>     writefln(base.classinfo.getMembers(m).length);

getMembers has not been implemented, AFAIK
March 30, 2009
On Mon, Mar 30, 2009 at 10:57 AM, Max Samukha <samukha@voliacable.com.removethis> wrote:
>>Also the following doesn't work with dmd, returns 0 for all members:
>>
>>Base base = new Base;
>>auto members = __traits(allMembers, typeof(base));
>>foreach(m; members)
>>     writefln(base.classinfo.getMembers(m).length);
>
> getMembers has not been implemented, AFAIK

It has in LDC ;)
March 30, 2009
On Mon, Mar 30, 2009 at 5:11 PM, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
> On Mon, Mar 30, 2009 at 10:57 AM, Max Samukha <samukha@voliacable.com.removethis> wrote:
>>>Also the following doesn't work with dmd, returns 0 for all members:
>>>
>>>Base base = new Base;
>>>auto members = __traits(allMembers, typeof(base));
>>>foreach(m; members)
>>>     writefln(base.classinfo.getMembers(m).length);
>>
>> getMembers has not been implemented, AFAIK
>
> It has in LDC ;)
>

I think we need D2 support first ;)
March 30, 2009
On Mon, Mar 30, 2009 at 11:13 AM, Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> wrote:
>>> getMembers has not been implemented, AFAIK
>>
>> It has in LDC ;)
>>
>
> I think we need D2 support first ;)

I was talking about the RTTI getMembers function :)
March 30, 2009
On Mon, Mar 30, 2009 at 5:13 PM, Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> wrote:
> On Mon, Mar 30, 2009 at 5:11 PM, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
>> On Mon, Mar 30, 2009 at 10:57 AM, Max Samukha <samukha@voliacable.com.removethis> wrote:
>>>>Also the following doesn't work with dmd, returns 0 for all members:
>>>>
>>>>Base base = new Base;
>>>>auto members = __traits(allMembers, typeof(base));
>>>>foreach(m; members)
>>>>     writefln(base.classinfo.getMembers(m).length);
>>>
>>> getMembers has not been implemented, AFAIK
>>
>> It has in LDC ;)
>>
>
> I think we need D2 support first ;)
>

Maybe you're thinking of OffsetTypeInfo (classinfo.offTi) ? Yes that can be enabled when configuring LDC, before building the compiler.
March 30, 2009
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?


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"
March 31, 2009
On Mon, 30 Mar 2009 22:04:57 +0200, Trass3r <mrmocool@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)));
        }
    }
}

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

>On Mon, 30 Mar 2009 22:04:57 +0200, Trass3r <mrmocool@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.
March 31, 2009
Max Samukha schrieb:
>> 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.
> 

So the docs are incorrect:
"getVirtualFunctions
The result is an array of the virtual overloads of that function."
« First   ‹ Prev
1 2 3