digitalmars.D.learn - Checking for manifest constants
- Bogdan (34/34) Mar 05 2021 I was using a trick with dmd to check for manifest constants
- Basile B. (15/49) Mar 05 2021 Hello, you can use this template instead:
- Petar Kirov [ZombineDev] (25/59) Mar 05 2021 I suggest this:
- bogdan (15/41) Mar 06 2021 Thanks!
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() {}
```
Mar 05 2021
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.
Mar 05 2021
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")));
}
Mar 05 2021
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: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[...]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"))); }
Mar 06 2021









Basile B. <b2.temp gmx.com> 