On Saturday, 30 July 2016 at 12:47:10 UTC, Jonathan M Davis wrote:
I'm writing some serialization code where I need to skip static
variables. So, I have a symbol from a struct, and I'd like to
test whether it's static or not. Ideally, I'd be able to do
something like
is(field == static)
but of course that doesn't work. There is
__traits(isStaticFunction, ...),
but there is no __traits(isStaticVariable, ...) or
__traits(isStatic, ...),
and I don't see anything in std.traits which would help. The
closest that
I've been able to come up with is
template isStaticVar(T, alias field)
{
enum isStaticVar =
is(typeof({mixin("auto i = T." ~ field.stringof ~
";");}));
}
For a more general solution, it would of course need to verify
that the field wasn't a function as well, but in my case, that
was already checked prior to instantiating isStaticVar, so I
can skip it here. And what I have mostly works. However, it
would fail miserably if the field were a static member variable
that was non-copyable. If it were, then that code would would
declare it to be non-static. Now, non-copyable structs are rare
enough that I can probably get away with letting that bug
stand, but I'd prefer to correctly detect whether a variable is
static or not. Does anyone have a better idea of how to do this?
- Jonathan M Davis
You won't be able to assign it if it's not static. Given this
isStaticVar(Stuff) = __traits(compiles, Stuff =
typeof(Stuff).init))
Unfortuantely it's hard to make a stand alone template for this.
For example I was not able to verify the non-static case
struct Foo
{
static int a;
int b;
}
template isStaticVar(alias stuff)
{
bool check()
{
bool result;
static if (!is(typeof(__traits(parent, stuff))))
result = true;
else static if (__traits(compiles, stuff =
typeof(stuff).init))
result = true;
return result;
}
enum isStaticVar = check();
}
unittest
{
static assert(isStaticVar!(Foo.a));
//static assert(isStaticVar!(Foo.b));
}
I'm curious to see the other solutions.