Skip to content

Commit e0ab406

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 e0ab406

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed

std/traits.d

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

0 commit comments

Comments
 (0)