-
-
Notifications
You must be signed in to change notification settings - Fork 755
Implement issue# 16485. Add trait for testing if a member is static. #4834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,7 @@ | |
| * $(LREF hasElaborateDestructor) | ||
| * $(LREF hasIndirections) | ||
| * $(LREF hasMember) | ||
| * $(LREF isStaticMember) | ||
| * $(LREF hasNested) | ||
| * $(LREF hasUnsharedAliasing) | ||
| * $(LREF InterfacesTuple) | ||
|
|
@@ -3340,6 +3341,170 @@ enum hasMember(T, string name) = __traits(hasMember, T, name); | |
| static assert(hasMember!(S, "foo")); | ||
| } | ||
|
|
||
| /++ | ||
| Whether the symbol represented by the string, member, is a static member of | ||
| T. | ||
| +/ | ||
| template isStaticMember(T, string member) | ||
| if (__traits(hasMember, T, member)) | ||
| { | ||
| import std.meta : Alias; | ||
| alias sym = Alias!(__traits(getMember, T, member)); | ||
|
|
||
| static if (__traits(getOverloads, T, member).length == 0) | ||
| enum bool isStaticMember = __traits(compiles, &sym); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure that it matters in this case, but there are subtle differences between the two, and I've been advised in the past to favor
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feels like a weird recommendation. I wonder if there is a compiler workload difference?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Andrei was the one who recommended the traits option to me, so you can probably ask him
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @TurkeyMan there is almost no difference.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In cases where this does hit your compile times you need a high n.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does 'accurate' mean? I've seen a bunch of weird recommendations emerging... they're not written anywhere. Are people just supposed to know?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @TurkeyMan It's more or less folk knowledge that's passed around. I don't think it's documented anywhere other than various forum threads. That said, it is definitely better to use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Right, and that's absolutely not okay! We're meant to be attracting new users. The meta experience is D's main offering, and new users should be able to get working and feel powerful with as little friction as possible. "Oh, yeah that obvious thing to type isn't actually what you do, you need to do this awkward unintuitive thing instead" is not something that's okay to say to new users.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not claiming it's obvious or ideal 😉 Just letting you know how things are. |
||
| else | ||
| enum bool isStaticMember = __traits(isStaticFunction, sym); | ||
| } | ||
|
|
||
| /// | ||
| unittest | ||
| { | ||
| static struct S | ||
| { | ||
| static void sf() {} | ||
| void f() {} | ||
|
|
||
| static int si; | ||
| int i; | ||
| } | ||
|
|
||
| static assert( isStaticMember!(S, "sf")); | ||
| static assert(!isStaticMember!(S, "f")); | ||
|
|
||
| static assert( isStaticMember!(S, "si")); | ||
| static assert(!isStaticMember!(S, "i")); | ||
|
|
||
| static assert(!__traits(compiles, isStaticMember!(S, "hello"))); | ||
| } | ||
|
|
||
| unittest | ||
| { | ||
| static struct S | ||
| { | ||
| enum X = 10; | ||
| enum Y | ||
| { | ||
| i = 10 | ||
| } | ||
| struct S {} | ||
| class C {} | ||
|
|
||
| static int sx = 0; | ||
| __gshared int gx = 0; | ||
|
|
||
| Y y; | ||
| static Y sy; | ||
|
|
||
| static void f() {} | ||
| static void f2() pure nothrow @nogc @safe {} | ||
|
|
||
| shared void g() {} | ||
|
|
||
| static void function() fp; | ||
| __gshared void function() gfp; | ||
| void function() fpm; | ||
|
|
||
| void delegate() dm; | ||
| static void delegate() sd; | ||
|
|
||
| void m() {} | ||
| final void m2() const pure nothrow @nogc @safe {} | ||
|
|
||
| inout(int) iom() inout { return 10; } | ||
| static inout(int) iosf(inout int x) { return x; } | ||
|
|
||
| @property int p() { return 10; } | ||
| static @property int sp() { return 10; } | ||
| } | ||
|
|
||
| static class C | ||
| { | ||
| enum X = 10; | ||
| enum Y | ||
| { | ||
| i = 10 | ||
| } | ||
| struct S {} | ||
| class C {} | ||
|
|
||
| static int sx = 0; | ||
| __gshared int gx = 0; | ||
|
|
||
| Y y; | ||
| static Y sy; | ||
|
|
||
| static void f() {} | ||
| static void f2() pure nothrow @nogc @safe {} | ||
|
|
||
| shared void g() {} | ||
|
|
||
| static void function() fp; | ||
| __gshared void function() gfp; | ||
| void function() fpm; | ||
|
|
||
| void delegate() dm; | ||
| static void delegate() sd; | ||
|
|
||
| void m() {} | ||
| final void m2() const pure nothrow @nogc @safe {} | ||
|
|
||
| inout(int) iom() inout { return 10; } | ||
| static inout(int) iosf(inout int x) { return x; } | ||
|
|
||
| @property int p() { return 10; } | ||
| static @property int sp() { return 10; } | ||
| } | ||
|
|
||
| static assert(!isStaticMember!(S, "X")); | ||
| static assert(!isStaticMember!(S, "Y")); | ||
| static assert(!__traits(compiles, isStaticMember!(S, "Y.i"))); | ||
| static assert(!isStaticMember!(S, "S")); | ||
| static assert(!isStaticMember!(S, "C")); | ||
| static assert( isStaticMember!(S, "sx")); | ||
| static assert( isStaticMember!(S, "gx")); | ||
| static assert(!isStaticMember!(S, "y")); | ||
| static assert( isStaticMember!(S, "sy")); | ||
| static assert( isStaticMember!(S, "f")); | ||
| static assert( isStaticMember!(S, "f2")); | ||
| static assert(!isStaticMember!(S, "dm")); | ||
| static assert( isStaticMember!(S, "sd")); | ||
| static assert(!isStaticMember!(S, "g")); | ||
| static assert( isStaticMember!(S, "fp")); | ||
| static assert( isStaticMember!(S, "gfp")); | ||
| static assert(!isStaticMember!(S, "fpm")); | ||
| static assert(!isStaticMember!(S, "m")); | ||
| static assert(!isStaticMember!(S, "m2")); | ||
| static assert(!isStaticMember!(S, "iom")); | ||
| static assert( isStaticMember!(S, "iosf")); | ||
| static assert(!isStaticMember!(S, "p")); | ||
| static assert( isStaticMember!(S, "sp")); | ||
|
|
||
| static assert(!isStaticMember!(C, "X")); | ||
| static assert(!isStaticMember!(C, "Y")); | ||
| static assert(!__traits(compiles, isStaticMember!(C, "Y.i"))); | ||
| static assert(!isStaticMember!(C, "S")); | ||
| static assert(!isStaticMember!(C, "C")); | ||
| static assert( isStaticMember!(C, "sx")); | ||
| static assert( isStaticMember!(C, "gx")); | ||
| static assert(!isStaticMember!(C, "y")); | ||
| static assert( isStaticMember!(C, "sy")); | ||
| static assert( isStaticMember!(C, "f")); | ||
| static assert( isStaticMember!(C, "f2")); | ||
| static assert(!isStaticMember!(S, "dm")); | ||
| static assert( isStaticMember!(S, "sd")); | ||
| static assert(!isStaticMember!(C, "g")); | ||
| static assert( isStaticMember!(C, "fp")); | ||
| static assert( isStaticMember!(C, "gfp")); | ||
| static assert(!isStaticMember!(C, "fpm")); | ||
| static assert(!isStaticMember!(C, "m")); | ||
| static assert(!isStaticMember!(C, "m2")); | ||
| static assert(!isStaticMember!(C, "iom")); | ||
| static assert( isStaticMember!(C, "iosf")); | ||
| static assert(!isStaticMember!(C, "p")); | ||
| static assert( isStaticMember!(C, "sp")); | ||
| } | ||
|
|
||
| /** | ||
| Retrieves the members of an enumerated type $(D enum E). | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs params and returns