partiallyQualifiedName?

Biotronic simen.kjaras at gmail.com
Tue Oct 17 06:38:52 UTC 2017


On Monday, 16 October 2017 at 23:56:00 UTC, Nicholas Wilson wrote:
> using fullyQualifiedName [here]
> (https://github.com/libmir/dcompute/blob/master/source/dcompute/driver/ocl/util.d#L120)
> leads to a large compilation slowdown, but I only need it to 
> disambiguate up to the module level i.e. so that
>
> struct Context
> {
>     enum Properties {}
>     static struct Info
>     {
>         @(0) Properties p; // <---
>     }
> }
>
> ...
> partiallyQualifiedName!p
> ...
>
> resolves to Context.Properties instead of 
> dcompute.driver.ocl.context.Context.Properties, thus avoiding 
> many template instantiations.
>
>  Alas typeof(p).stringof, which yields Properties, errors "No 
> such identifier Properties" (and subsequently crashes the CTFE 
> engine).
>
> I tried looking at the fullyQualifiedName but got lost pretty 
> quick.

If I understand things correctly, you only care about enums 
nested in scopes up to the module scope, right? If so, this seems 
to fit the bill:

enum A {a}

struct S {
     enum B {b}
     struct S2 {
         enum C {c}
         C c;
     }
     A a;
     B b;
     int n, m;
     pragma(msg, partiallyQualifiedName!n); // S.n
     pragma(msg, partiallyQualifiedName!(S2)); // S.S2
     pragma(msg, partiallyQualifiedName!(typeof(a))); // A
     pragma(msg, partiallyQualifiedName!(typeof(b))); // S.B
     pragma(msg, partiallyQualifiedName!(typeof(S2.c))); // S.S2.C
     pragma(msg, partiallyQualifiedName!(a)); // S.a
     pragma(msg, partiallyQualifiedName!(b)); // S.b
     pragma(msg, partiallyQualifiedName!(S2.c)); // S.S2.c
}

template isModule(alias a) {
     static if (is(a) || is(typeof(a)) || a.stringof.length < 7) {
         enum isModule = false;
     } else {
         enum isModule = a.stringof[0..7] == "module ";
     }
}

template partiallyQualifiedName(alias a) {
     static if (isModule!a) {
         enum partiallyQualifiedName = "";
     } else {
         static if (!isModule!(__traits(parent, a))) {
             enum prefix = 
partiallyQualifiedName!(__traits(parent, a)) ~ ".";
         } else {
             enum prefix = "";
         }
         enum partiallyQualifiedName = prefix ~ 
__traits(identifier, a);
     }
}

Note that it fails for built-in types, arrays, and many other 
cases, and does not support const/immutable/shared/etc. It should 
cover the cases described, though, and that's what's most 
important. If more support is needed, consider it a starting 
point, and feel free to ask for more. :)

--
   Biotronic


More information about the Digitalmars-d-learn mailing list