Detecting manifest contants

Basile B. b2.temp at gmx.com
Sun Mar 13 08:10:37 UTC 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;
}
```



More information about the Digitalmars-d-learn mailing list