digitalmars.D.learn - Using std traits
- JN (39/39) Jan 25 2018 I decided it's time to learn how std traits work. I still find
- =?UTF-8?Q?Ali_=c3=87ehreli?= (26/32) Jan 25 2018 'member' is a string local variable, which does not have that UDA. You
- JN (5/6) Jan 25 2018 Nevermind, I get it now, member is only the field name, not a
I decided it's time to learn how std traits work. I still find
the whole compile time business a bit weird to deal with, so I
decided to write a simple JSON serializer for struct that loops
over member fields and outputs them.
import std.stdio;
import std.json;
import std.traits;
struct TestStruct
{
("noserialize") int x;
int y;
int z;
}
void serialize(T)(T obj)
{
if (is(T == struct))
{
foreach (i, member; FieldNameTuple!T)
{
if (!hasUDA!(member, "noserialize"))
{
writeln(member);
}
}
} else {
assert(0, "Not a struct");
}
}
void main()
{
TestStruct ts;
ts.x = 1;
ts.y = 2;
ts.z = 3;
serialize(ts);
}
here's a runnable version: https://ideone.com/U4ROAT
I expected it to output "y" "z", but "x" is also present. What am
I doing wrong with hasUDA?
Jan 25 2018
On 01/25/2018 11:49 AM, JN wrote:
foreach (i, member; FieldNameTuple!T)
{
if (!hasUDA!(member, "noserialize"))
{
writeln(member);
}
'member' is a string local variable, which does not have that UDA. You
need to get the symbol of the struct:
if (!hasUDA!(__traits(getMember, T, member), "noserialize"))
{
writeln(member);
}
However, note that you're using a compile-time foreach, which expands
its body for each iteration. Since you used a regular if, you have three
checks at runtime.
What you really want is use a 'static if':
static if (!hasUDA!(__traits(getMember, T, member),
"noserialize"))
{
writeln(member);
}
Aaah... Much lighter... :)
Even further, you may want to consider using a 'static foreach':
static foreach (i, member; FieldNameTuple!T)
{
// ...
}
That is more powerful because it can iterate over more ranges. However
there are some differences from the regular foreach: For example,
'static foreach' does not introduce a scope per iteration.
Ali
Jan 25 2018
On Thursday, 25 January 2018 at 19:49:05 UTC, JN wrote:if (!hasUDA!(member, "noserialize"))Nevermind, I get it now, member is only the field name, not a 'reference', changed it to: if (!hasUDA!(mixin(T.stringof ~ "." ~ member), "noserialize")) and works now
Jan 25 2018









=?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> 