Getting only the data members of a type

Ali Çehreli acehreli at yahoo.com
Sat Mar 31 23:18:08 PDT 2012


On 03/31/2012 09:09 PM, Artur Skawina wrote:
 > On 03/31/12 21:09, Ali Çehreli wrote:
 >> How can I determine just the data members of a struct or class, 
excluding the member functions? isCallable() comes short as member 
variable that have opCall() defined are also callable:
 > [...]
 >> Wait! I found a solution before sending this message. :P 
isIntegral() works:
 >>
 >>          if (isIntegral!(typeof(mixin("S." ~ member)))) {
 >>
 >> Now the output is:
 >>
 >>      i is a member function
 >>      m is a member variable<-- good but dubious
 >>    foo is a member variable
 > [...]
 >
 > Don't forget about templates (appear as members too, but don't have a 
type).

I see. We can't even use isCallable or isIntegral with a template 
member. Assuming S has this member function template:

     void bar(T)()
     {}

Then we get the following error:

/usr/include/d/dmd/phobos/std/traits.d(3223): Error: (S).bar(T) has no value

I don't know a way of saying "if a template".

 > This will print all fields of struct/class S:
 >
 >     enum s = cast(S*)null;
 >     foreach (i, m; s.tupleof) {
 >        enum name = S.tupleof[i].stringof[4..$];
 >        alias typeof(m) type;
 >        writef("(%s) %s\n", type.stringof, name);
 >     }
 >
 > Real Programmers don't use std.traits. ;)
 >
 > artur

Your method works but needing to iterate on a struct variable by 
s.tupleof and having to use the struct type as S.tupleof in the loop 
body is strange.

Looks like S.tupleof[i].stringof is the answer for what I was looking for:

import std.stdio;
import std.traits;

struct M
{
     int i;

     this(int i)
     {
         this.i = i;
     }

     void opCall()
     {}
}

struct S
{
     int i;
     M m;

     void foo()
     {}

     void bar(T)()
     {}
}

void main()
{
     enum s = S(42, M(7));

     foreach (i, m; s.tupleof) {
         writefln("%s:", i);

         enum name = S.tupleof[i].stringof[4..$];
         alias typeof(m) type;
         writefln("  S.tupleof[i]: %s", S.tupleof[i].stringof);
         writefln("  (type) name : (%s) %s", type.stringof, name);

         writefln("  m           : %s", m);
         writefln("  m.stringof  : %s", m.stringof);
     }
}

The output:

0:
   S.tupleof[i]: (S).i
   (type) name : (int) i
   m           : 42
   m.stringof  : 42
1:
   S.tupleof[i]: (S).m
   (type) name : (M) m
   m           : M(7)
   m.stringof  : m

Ali



More information about the Digitalmars-d-learn mailing list