Jump to page: 1 2
Thread overview
How do you test whether a variable is static or not?
Jul 30, 2016
Jonathan M Davis
Jul 30, 2016
Ali Çehreli
Jul 30, 2016
Basile B.
Jul 30, 2016
Jonathan M Davis
Jun 16, 2018
DigitalDesigns
Jun 16, 2018
Bauss
Jul 30, 2016
Basile B.
Jun 16, 2018
Jonathan M Davis
Jun 16, 2018
Jonathan M Davis
Jun 16, 2018
DigitalDesigns
Jun 16, 2018
Jonathan M Davis
July 30, 2016
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

July 30, 2016
On 07/30/2016 05:47 AM, Jonathan M Davis via Digitalmars-d-learn 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.

static variables don't have the .offsetof property:

struct S {
    int a;
    static int b;
}


// Bonus question: should field be alias or string?
template isStaticVar(T, alias field)
{
    enum isStaticVar = !__traits(compiles, mixin("T." ~ field ~ ".offsetof"));
}

void main() {
    static assert (!isStaticVar!(S, "a"));
    static assert (isStaticVar!(S, "b"));
}

Ali

July 30, 2016
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.
July 30, 2016
On Saturday, 30 July 2016 at 13:04:56 UTC, Ali Çehreli wrote:
> On 07/30/2016 05:47 AM, Jonathan M Davis via Digitalmars-d-learn 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.
>
> static variables don't have the .offsetof property:
>
> struct S {
>     int a;
>     static int b;
> }
>
>
> // Bonus question: should field be alias or string?
> template isStaticVar(T, alias field)
> {
>     enum isStaticVar = !__traits(compiles, mixin("T." ~ field ~ ".offsetof"));
> }
>
> void main() {
>     static assert (!isStaticVar!(S, "a"));
>     static assert (isStaticVar!(S, "b"));
> }
>
> Ali

Wow, this is directly for std.traits !
July 30, 2016
On Saturday, July 30, 2016 06:04:56 Ali Çehreli via Digitalmars-d-learn wrote:
> On 07/30/2016 05:47 AM, Jonathan M Davis via Digitalmars-d-learn 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.
>
> static variables don't have the .offsetof property:
>
> struct S {
>      int a;
>      static int b;
>
> // Bonus question: should field be alias or string?

That depends on what you're doing. __traits(allMembers, ...) gives you a list of strings, so it may make more sense in the general case to use string, but in order to actually do much of anything useful, you have to convert them all to symbols, which is what I've done in my code and why I was using an alias.

> template isStaticVar(T, alias field)
> {
>      enum isStaticVar = !__traits(compiles, mixin("T." ~ field ~
> ".offsetof"));
> }
>
> void main() {
>      static assert (!isStaticVar!(S, "a"));
>      static assert (isStaticVar!(S, "b"));
> }

Thanks!

- Jonathan M Davis


June 16, 2018
On Saturday, 30 July 2016 at 13:04:56 UTC, Ali Çehreli wrote:
> On 07/30/2016 05:47 AM, Jonathan M Davis via Digitalmars-d-learn 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.
>
> static variables don't have the .offsetof property:
>
> struct S {
>     int a;
>     static int b;
> }
>
>
> // Bonus question: should field be alias or string?
> template isStaticVar(T, alias field)
> {
>     enum isStaticVar = !__traits(compiles, mixin("T." ~ field ~ ".offsetof"));
> }
>
> void main() {
>     static assert (!isStaticVar!(S, "a"));
>     static assert (isStaticVar!(S, "b"));
> }
>
> Ali

This doesn't work, treats fields in base classes as static.

One way to test if a member is static is if it it doesn't exist in tupleof... but this only returns the immediate members and so will fail.  I guess one will have to check all base types too and if it doesn't exist in any of then it should be static.

Why is it so hard to be able to get basic information like if a type is static or not?
June 16, 2018
On Saturday, 16 June 2018 at 08:52:20 UTC, DigitalDesigns wrote:
> On Saturday, 30 July 2016 at 13:04:56 UTC, Ali Çehreli wrote:
>> On 07/30/2016 05:47 AM, Jonathan M Davis via Digitalmars-d-learn 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.
>>
>> static variables don't have the .offsetof property:
>>
>> struct S {
>>     int a;
>>     static int b;
>> }
>>
>>
>> // Bonus question: should field be alias or string?
>> template isStaticVar(T, alias field)
>> {
>>     enum isStaticVar = !__traits(compiles, mixin("T." ~ field ~ ".offsetof"));
>> }
>>
>> void main() {
>>     static assert (!isStaticVar!(S, "a"));
>>     static assert (isStaticVar!(S, "b"));
>> }
>>
>> Ali
>
> This doesn't work, treats fields in base classes as static.
>
> One way to test if a member is static is if it it doesn't exist in tupleof... but this only returns the immediate members and so will fail.  I guess one will have to check all base types too and if it doesn't exist in any of then it should be static.
>
> Why is it so hard to be able to get basic information like if a type is static or not?

Probably because the symbols don't carry the information. I'd reckon a compiler addition to __traits() would probably solve this. Something like getStaticMembers
June 16, 2018
On 7/30/16 8:47 AM, Jonathan M Davis via Digitalmars-d-learn 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)

std.traits.hasStaticMember ?

https://dlang.org/phobos/std_traits.html#hasStaticMember

-Steve
June 16, 2018
On Saturday, June 16, 2018 14:55:51 Steven Schveighoffer via Digitalmars-d- learn wrote:
> On 7/30/16 8:47 AM, Jonathan M Davis via Digitalmars-d-learn 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)
>
> std.traits.hasStaticMember ?
>
> https://dlang.org/phobos/std_traits.html#hasStaticMember

Yeah. I wrote that, and it got added to Phobos. If you'll note, my post in this thread was from almost two years ago.

- Jonathan M Davis

June 16, 2018
On Saturday, 16 June 2018 at 21:41:37 UTC, Jonathan M Davis wrote:
> On Saturday, June 16, 2018 14:55:51 Steven Schveighoffer via Digitalmars-d- learn wrote:
>> On 7/30/16 8:47 AM, Jonathan M Davis via Digitalmars-d-learn 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)
>>
>> std.traits.hasStaticMember ?
>>
>> https://dlang.org/phobos/std_traits.html#hasStaticMember
>
> Yeah. I wrote that, and it got added to Phobos. If you'll note, my post in this thread was from almost two years ago.
>

Haha! I usually don’t get caught with these old threads!

-Steve


« First   ‹ Prev
1 2