digitalmars.D.learn - Detecting manifest contants
- Anonymouse (29/29) Mar 12 2022 I'm introspecting structs, and I ran into an issue where
- Paul Backus (2/6) Mar 12 2022 It sounds like what you want here is `.tupleo`.
- Paul Backus (2/9) Mar 12 2022 Typo: `.tupleof`
- Anonymouse (4/5) Mar 12 2022 I use `.tupleof` otherwise, but this is old stuff from when I
- Basile B. (42/71) Mar 13 2022 A way is to try declaring an enum with the value returned by the
I'm introspecting structs, and I ran into an issue where `__traits(derivedMembers)` includes manifest constant enums in the returned tuple. What is the correct way to statically detect these? The immediate thing that springs to mind is `is(symbol == enum)`, but it's not it. Currently I'm testing if a function that takes the address of the member compiles, and I think it works, but like with everything `__traits(compiles)` it strikes me as it might not be the right way to go about things. ```d struct Foo { int i; enum k = 42; } void main() { foreach (memberstring; __traits(derivedMembers, Foo)) { static if (__traits(compiles, { Foo f; auto ptr = &__traits(getMember, f, memberstring); })) { // ... } } } ``` What else can I try?
Mar 12 2022
On Saturday, 12 March 2022 at 18:49:32 UTC, Anonymouse wrote:Currently I'm testing if a function that takes the address of the member compiles, and I think it works, but like with everything `__traits(compiles)` it strikes me as it might not be the right way to go about things.It sounds like what you want here is `.tupleo`.
Mar 12 2022
On Saturday, 12 March 2022 at 19:00:23 UTC, Paul Backus wrote:On Saturday, 12 March 2022 at 18:49:32 UTC, Anonymouse wrote:Typo: `.tupleof`Currently I'm testing if a function that takes the address of the member compiles, and I think it works, but like with everything `__traits(compiles)` it strikes me as it might not be the right way to go about things.It sounds like what you want here is `.tupleo`.
Mar 12 2022
On Saturday, 12 March 2022 at 19:01:06 UTC, Paul Backus wrote:Typo: `.tupleof`I use `.tupleof` otherwise, but this is old stuff from when I didn't know of it. I'll have to refactor it some day, I had hoped for it to be just... not yet.
Mar 12 2022
On Saturday, 12 March 2022 at 18:49:32 UTC, Anonymouse wrote:I'm introspecting structs, and I ran into an issue where `__traits(derivedMembers)` includes manifest constant enums in the returned tuple. What is the correct way to statically detect these? The immediate thing that springs to mind is `is(symbol == enum)`, but it's not it. Currently I'm testing if a function that takes the address of the member compiles, and I think it works, but like with everything `__traits(compiles)` it strikes me as it might not be the right way to go about things. ```d struct Foo { int i; enum k = 42; } void main() { foreach (memberstring; __traits(derivedMembers, Foo)) { static if (__traits(compiles, { Foo f; auto ptr = &__traits(getMember, f, memberstring); })) { // ... } } } ``` What else can I try?A way is to try declaring an enum with the value returned by the `getMember` trait. ```d /** * Indicates wether something is a value known at compile time. * * Params: * V = The value to test. * T = Optional, the expected value type. */ template isCompileTimeValue(alias V, T...) if (T.length == 0 || (T.length == 1 && is(T[0]))) { enum isKnown = is(typeof((){enum v = V;})); static if (!T.length) enum isCompileTimeValue = isKnown; else enum isCompileTimeValue = isKnown && is(typeof(V) == T[0]); } /// unittest { string a; enum b = "0"; enum c = 0; static assert(!isCompileTimeValue!a); static assert(isCompileTimeValue!b); static assert(isCompileTimeValue!c); static assert(isCompileTimeValue!(b,string)); static assert(isCompileTimeValue!(c,int)); static assert(!isCompileTimeValue!(c,char)); static assert(!isCompileTimeValue!(char)); } /// ditto template isCompileTimeValue(V, T...) if (T.length == 0 || (T.length == 1 && is(T[0]))) { enum isCompileTimeValue = false; } ```
Mar 13 2022