digitalmars.D.learn - partiallyQualifiedName?
- Nicholas Wilson (25/25) Oct 16 2017 using fullyQualifiedName [here]
- Stefan Koch (3/28) Oct 16 2017 This should really be done via a __trait. Otherwise it does not
- Biotronic (51/74) Oct 16 2017 If I understand things correctly, you only care about enums
- Nicholas Wilson (5/57) Oct 17 2017 Yes I only need it for enums due to it being a new type, the rest
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. Thanks Nic
Oct 16 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. Thanks NicThis should really be done via a __trait. Otherwise it does not scale.
Oct 16 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
Oct 16 2017
On Tuesday, 17 October 2017 at 06:38:52 UTC, Biotronic wrote: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. :) -- BiotronicYes I only need it for enums due to it being a new type, the rest are all builtin basic types. static if(is(typeof(X) == enum)) should do the trick for the rest. Thanks!
Oct 17 2017