Fastest way to check using if identifier has already been defined, using static if or similar?
Simen Kjærås
simen.kjaras at gmail.com
Thu Jun 4 09:03:40 UTC 2020
On Wednesday, 3 June 2020 at 15:25:51 UTC, Paul Backus wrote:
> On Wednesday, 3 June 2020 at 13:24:17 UTC, Basile B. wrote:
>> This is because the template parameter must be resolved to a
>> valid symbol or type.
>> This version other version bypass the problem:
>>
>> ---
>> enum Exists(string s) = is(typeof(mixin(s)));
>>
>> void main()
>> {
>> static if (!Exists!"foo")
>> int foo;
>> foo = 42;
>> }
>> ---
>
> Fails if the symbol in question is the name of a type.
>
> struct Foo {}
> enum Exists(string s) = is(typeof(mixin(s)));
> static assert(Exists!"Foo"); // false
>
> What you actually want is something like this:
>
> enum Exists(string s) = __traits(compiles, { mixin("alias _
> = ", s, ";"); });
And they both fail if the thing you refer to isn't available in
the scope where Exists is defined. I believe this covers most
cases, but there may very well be corner cases I haven't
considered:
string exists(string s) {
return "__traits(compiles, { mixin(\"alias _ = "~s~";\"); })";
}
// Handles values:
int global;
unittest {
int local;
{
int outOfScope;
}
static assert(mixin("local".exists));
static assert(mixin("global".exists));
static assert(!mixin("outOfScope".exists));
}
// And types:
struct Global {}
unittest {
struct Local {}
{
struct OutOfScope;
}
static assert(mixin("Global".exists));
static assert(mixin("Local".exists));
static assert(!mixin("OutOfScope".exists));
}
// But not expressions:
static assert(!mixin("1+2".exists));
// Correctly fails for missing declarations:
static assert(!mixin("nowhere".exists));
Like Stefan said though, we're quite a bit off from the original
request - the above certainly shouldn't be faster than drathier's
original code. The only advantage I see is that it might read a
little clearer.
--
Simen
More information about the Digitalmars-d-learn
mailing list