| |
| Posted by Basile B. in reply to Anonymouse | PermalinkReply |
|
Basile B.
Posted in reply to Anonymouse
| 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.
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.
/**
* 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;
}
|