Getting only the data members of a type
Artur Skawina
art.08.09 at gmail.com
Sun Apr 1 02:27:50 PDT 2012
On 04/01/12 08:18, Ali Çehreli wrote:
> 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".
eg:
static if (!__traits(compiles, &__traits(getMember, obj, name)))
or just
static if (!is(typeof(member)))
>> 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.
That's because the compiler won't accept "foreach (i, t; S.tupleof)" and
"*.tupleof[i].stringof" is necessary to get the original name. This would
have worked too:
enum name = *s.tupleof[i].stringof[4..$];
but obfuscates the code more and looks like dereferencing a null pointer.
artur
More information about the Digitalmars-d-learn
mailing list