Thread overview | ||||||
---|---|---|---|---|---|---|
|
March 05, 2021 Checking for manifest constants | ||||
---|---|---|---|---|
| ||||
I was using a trick with dmd to check for manifest constants which worked until dmd v2.094. Yesterday I tried it on the latest compiler and it failed with: source/introspection/manifestConstant.d(37,28): Error: need this for name of type string source/introspection/type.d(156,13): Error: value of this is not known at compile time any ideas how to fix it? or, is it a bug with dmd? ``` /// Check if a member is manifest constant bool isManifestConstant(T, string name)() { mixin(`return is(typeof(T.init.` ~ name ~ `)) && !is(typeof(&T.init.` ~ name ~ `));`); } /// ditto bool isManifestConstant(alias T)() { return is(typeof(T)) && !is(typeof(&T)); } enum globalConfig = 32; int globalValue = 22; unittest { struct Test { enum config = 3; int value = 2; } static assert(isManifestConstant!(Test.config)); static assert(isManifestConstant!(Test, "config")); static assert(isManifestConstant!(globalConfig)); static assert(!isManifestConstant!(Test.value)); static assert(!isManifestConstant!(Test, "value")); static assert(!isManifestConstant!(globalValue)); } void main() {} ``` |
March 05, 2021 Re: Checking for manifest constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bogdan | On Friday, 5 March 2021 at 08:23:09 UTC, Bogdan wrote:
> I was using a trick with dmd to check for manifest constants which worked until dmd v2.094. Yesterday I tried it on the latest compiler and it failed with:
>
>
> source/introspection/manifestConstant.d(37,28): Error: need this for name of type string
> source/introspection/type.d(156,13): Error: value of this is not known at compile time
>
> any ideas how to fix it? or, is it a bug with dmd?
>
> ```
>
> /// Check if a member is manifest constant
> bool isManifestConstant(T, string name)() {
> mixin(`return is(typeof(T.init.` ~ name ~ `)) && !is(typeof(&T.init.` ~ name ~ `));`);
> }
>
> /// ditto
> bool isManifestConstant(alias T)() {
> return is(typeof(T)) && !is(typeof(&T));
> }
>
> enum globalConfig = 32;
> int globalValue = 22;
>
> unittest {
> struct Test {
> enum config = 3;
> int value = 2;
> }
>
> static assert(isManifestConstant!(Test.config));
> static assert(isManifestConstant!(Test, "config"));
> static assert(isManifestConstant!(globalConfig));
>
> static assert(!isManifestConstant!(Test.value));
> static assert(!isManifestConstant!(Test, "value"));
> static assert(!isManifestConstant!(globalValue));
> }
>
> void main() {}
>
>
> ```
Hello, you can use this template instead:
template isManifestConstant(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 isManifestConstant = isKnown;
else
enum isManifestConstant = isKnown && is(typeof(V) == T[0]);
}
The optional T is to verify if it is a compile time constant of a certain type.
the tests you wrote and that are not based on a string pass.
|
March 05, 2021 Re: Checking for manifest constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bogdan | On Friday, 5 March 2021 at 08:23:09 UTC, Bogdan wrote: > I was using a trick with dmd to check for manifest constants which worked until dmd v2.094. Yesterday I tried it on the latest compiler and it failed with: > > > source/introspection/manifestConstant.d(37,28): Error: need this for name of type string > source/introspection/type.d(156,13): Error: value of this is not known at compile time > > any ideas how to fix it? or, is it a bug with dmd? > > ``` > > /// Check if a member is manifest constant > bool isManifestConstant(T, string name)() { > mixin(`return is(typeof(T.init.` ~ name ~ `)) && !is(typeof(&T.init.` ~ name ~ `));`); > } > > /// ditto > bool isManifestConstant(alias T)() { > return is(typeof(T)) && !is(typeof(&T)); > } > > enum globalConfig = 32; > int globalValue = 22; > > unittest { > struct Test { > enum config = 3; > int value = 2; > } > > static assert(isManifestConstant!(Test.config)); > static assert(isManifestConstant!(Test, "config")); > static assert(isManifestConstant!(globalConfig)); > > static assert(!isManifestConstant!(Test.value)); > static assert(!isManifestConstant!(Test, "value")); > static assert(!isManifestConstant!(globalValue)); > } > > void main() {} > > > ``` I suggest this: enum globalConfig = 32; int globalValue = 22; immutable globaImmutablelValue = 22; enum isManifestConstant(alias symbol) = __traits(compiles, { enum e = symbol; }) && !__traits(compiles, { const ptr = &symbol; }); unittest { struct Test { enum config = 3; int value = 2; } static assert(isManifestConstant!(Test.config)); static assert(isManifestConstant!(mixin("Test.config"))); static assert(isManifestConstant!(globalConfig)); static assert(isManifestConstant!(mixin("globalConfig"))); static assert(!isManifestConstant!(Test.value)); static assert(!isManifestConstant!(mixin("Test.value"))); static assert(!isManifestConstant!(globalValue)); static assert(!isManifestConstant!(mixin("globalValue"))); static assert(!isManifestConstant!(globaImmutablelValue)); static assert(!isManifestConstant!(mixin("globaImmutablelValue"))); } |
March 06, 2021 Re: Checking for manifest constants | ||||
---|---|---|---|---|
| ||||
Posted in reply to Petar Kirov [ZombineDev] | On Friday, 5 March 2021 at 14:42:07 UTC, Petar Kirov [ZombineDev] wrote: > On Friday, 5 March 2021 at 08:23:09 UTC, Bogdan wrote: >> [...] > > I suggest this: > > enum globalConfig = 32; > int globalValue = 22; > immutable globaImmutablelValue = 22; > > enum isManifestConstant(alias symbol) = > __traits(compiles, { enum e = symbol; }) && > !__traits(compiles, { const ptr = &symbol; }); > > unittest { > struct Test { > enum config = 3; > int value = 2; > } > > static assert(isManifestConstant!(Test.config)); > static assert(isManifestConstant!(mixin("Test.config"))); > > static assert(isManifestConstant!(globalConfig)); > static assert(isManifestConstant!(mixin("globalConfig"))); > > static assert(!isManifestConstant!(Test.value)); > static assert(!isManifestConstant!(mixin("Test.value"))); > > static assert(!isManifestConstant!(globalValue)); > static assert(!isManifestConstant!(mixin("globalValue"))); > > static assert(!isManifestConstant!(globaImmutablelValue)); > static assert(!isManifestConstant!(mixin("globaImmutablelValue"))); > } Thanks! I ended using this: ``` /// Check if a member is manifest constant enum isManifestConstant(T, string name) = isManifestConstant!(__traits(getMember, T, name)); /// ditto enum isManifestConstant(alias symbol) = __traits(compiles, { enum e = symbol; }) && !__traits(compiles, { const ptr = &symbol; }); ``` It looks like mixin does not work well with protected/private members |
Copyright © 1999-2021 by the D Language Foundation