Skip to content

Commit 992dbb8

Browse files
committed
Implement issue# 16485. Add trait for testing if a member is static.
isStaticMember tests whether a member of a struct or class is static or not. It works with both functions and variables.
1 parent bf010cd commit 992dbb8

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

std/traits.d

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* $(LREF hasElaborateDestructor)
4444
* $(LREF hasIndirections)
4545
* $(LREF hasMember)
46+
* $(LREF isStaticMember)
4647
* $(LREF hasNested)
4748
* $(LREF hasUnsharedAliasing)
4849
* $(LREF InterfacesTuple)
@@ -3340,6 +3341,173 @@ enum hasMember(T, string name) = __traits(hasMember, T, name);
33403341
static assert(hasMember!(S, "foo"));
33413342
}
33423343

3344+
/++
3345+
Whether the symbol represented by the string, member, is a static member of
3346+
T.
3347+
+/
3348+
template isStaticMember(T, string member)
3349+
if(__traits(hasMember, T, member))
3350+
{
3351+
import std.meta : AliasSeq;
3352+
import std.traits : FunctionTypeOf;
3353+
alias sym = AliasSeq!(__traits(getMember, T, member))[0];
3354+
3355+
static if (is(typeof(sym) == function))
3356+
enum bool isStaticMember = __traits(isStaticFunction, sym);
3357+
else static if (is(FunctionTypeOf!(typeof(&sym)) == function))
3358+
enum bool isStaticMember = __traits(isStaticFunction, sym);
3359+
else
3360+
enum bool isStaticMember = __traits(compiles, &sym);
3361+
}
3362+
3363+
///
3364+
unittest
3365+
{
3366+
static struct S
3367+
{
3368+
static void sf() {}
3369+
void f() {}
3370+
3371+
static int si;
3372+
int i;
3373+
}
3374+
3375+
static assert( isStaticMember!(S, "sf"));
3376+
static assert(!isStaticMember!(S, "f"));
3377+
3378+
static assert( isStaticMember!(S, "si"));
3379+
static assert(!isStaticMember!(S, "i"));
3380+
3381+
static assert(!__traits(compiles, isStaticMember!(S, "hello")));
3382+
}
3383+
3384+
unittest
3385+
{
3386+
static struct S
3387+
{
3388+
enum X = 10;
3389+
enum Y
3390+
{
3391+
i = 10
3392+
}
3393+
struct S {}
3394+
class C {}
3395+
3396+
static int sx = 0;
3397+
__gshared int gx = 0;
3398+
3399+
Y y;
3400+
static Y sy;
3401+
3402+
static void f() {}
3403+
static void f2() pure nothrow @nogc @safe {}
3404+
3405+
shared void g() {}
3406+
3407+
static void function() fp;
3408+
__gshared void function() gfp;
3409+
void function() fpm;
3410+
3411+
void delegate() dm;
3412+
static void delegate() sd;
3413+
3414+
void m() {}
3415+
final void m2() const pure nothrow @nogc @safe {}
3416+
3417+
inout(int) iom() inout { return 10; }
3418+
static inout(int) iosf(inout int x) { return x; }
3419+
3420+
@property int p() { return 10; }
3421+
static @property int sp() { return 10; }
3422+
}
3423+
3424+
static class C
3425+
{
3426+
enum X = 10;
3427+
enum Y
3428+
{
3429+
i = 10
3430+
}
3431+
struct S {}
3432+
class C {}
3433+
3434+
static int sx = 0;
3435+
__gshared int gx = 0;
3436+
3437+
Y y;
3438+
static Y sy;
3439+
3440+
static void f() {}
3441+
static void f2() pure nothrow @nogc @safe {}
3442+
3443+
shared void g() {}
3444+
3445+
static void function() fp;
3446+
__gshared void function() gfp;
3447+
void function() fpm;
3448+
3449+
void delegate() dm;
3450+
static void delegate() sd;
3451+
3452+
void m() {}
3453+
final void m2() const pure nothrow @nogc @safe {}
3454+
3455+
inout(int) iom() inout { return 10; }
3456+
static inout(int) iosf(inout int x) { return x; }
3457+
3458+
@property int p() { return 10; }
3459+
static @property int sp() { return 10; }
3460+
}
3461+
3462+
static assert(!isStaticMember!(S, "X"));
3463+
static assert(!isStaticMember!(S, "Y"));
3464+
static assert(!__traits(compiles, isStaticMember!(S, "Y.i")));
3465+
static assert(!isStaticMember!(S, "S"));
3466+
static assert(!isStaticMember!(S, "C"));
3467+
static assert( isStaticMember!(S, "sx"));
3468+
static assert( isStaticMember!(S, "gx"));
3469+
static assert(!isStaticMember!(S, "y"));
3470+
static assert( isStaticMember!(S, "sy"));
3471+
static assert( isStaticMember!(S, "f"));
3472+
static assert( isStaticMember!(S, "f2"));
3473+
static assert(!isStaticMember!(S, "dm"));
3474+
static assert( isStaticMember!(S, "sd"));
3475+
static assert(!isStaticMember!(S, "g"));
3476+
static assert( isStaticMember!(S, "fp"));
3477+
static assert( isStaticMember!(S, "gfp"));
3478+
static assert(!isStaticMember!(S, "fpm"));
3479+
static assert(!isStaticMember!(S, "m"));
3480+
static assert(!isStaticMember!(S, "m2"));
3481+
static assert(!isStaticMember!(S, "iom"));
3482+
static assert( isStaticMember!(S, "iosf"));
3483+
static assert(!isStaticMember!(S, "p"));
3484+
static assert( isStaticMember!(S, "sp"));
3485+
3486+
static assert(!isStaticMember!(C, "X"));
3487+
static assert(!isStaticMember!(C, "Y"));
3488+
static assert(!__traits(compiles, isStaticMember!(C, "Y.i")));
3489+
static assert(!isStaticMember!(C, "S"));
3490+
static assert(!isStaticMember!(C, "C"));
3491+
static assert( isStaticMember!(C, "sx"));
3492+
static assert( isStaticMember!(C, "gx"));
3493+
static assert(!isStaticMember!(C, "y"));
3494+
static assert( isStaticMember!(C, "sy"));
3495+
static assert( isStaticMember!(C, "f"));
3496+
static assert( isStaticMember!(C, "f2"));
3497+
static assert(!isStaticMember!(S, "dm"));
3498+
static assert( isStaticMember!(S, "sd"));
3499+
static assert(!isStaticMember!(C, "g"));
3500+
static assert( isStaticMember!(C, "fp"));
3501+
static assert( isStaticMember!(C, "gfp"));
3502+
static assert(!isStaticMember!(C, "fpm"));
3503+
static assert(!isStaticMember!(C, "m"));
3504+
static assert(!isStaticMember!(C, "m2"));
3505+
static assert(!isStaticMember!(C, "iom"));
3506+
static assert( isStaticMember!(C, "iosf"));
3507+
static assert(!isStaticMember!(C, "p"));
3508+
static assert( isStaticMember!(C, "sp"));
3509+
}
3510+
33433511
/**
33443512
Retrieves the members of an enumerated type $(D enum E).
33453513

0 commit comments

Comments
 (0)