How to stringify a template instantiation expression?

Simen Kjærås simen.kjaras at gmail.com
Thu Mar 1 17:48:02 UTC 2018


On Thursday, 1 March 2018 at 16:46:30 UTC, Yuxuan Shui wrote:
> On Wednesday, 28 February 2018 at 15:49:25 UTC, aliak wrote:
>> On Wednesday, 28 February 2018 at 15:09:56 UTC, Yuxuan Shui 
>> wrote:
>>> For a template instantiation expression like A!(B, C!(D, E)), 
>>> I want to get a string "A!(B, C!(D, E))", better if A, B, C, 
>>> D, E is replaced by fully qualified name.
>>>
>>> Is this possible?
>>
>> A!(B, C!(D, E)).stringof I guess. Will print the former.
>>
>> There's a Learn forum as well btw :)
>>
>> Cheers
>
> Did you actually try that? With dmd 2.079-rc1, this:
>
> template A(T...) {}
> struct B {}
> struct D {}
> struct E {}
> template C(T...) {}
> pragma(msg, (A!(B, C!(D, E))).stringof);
>
> Prints:
>
> A!(B, __T1CTS2ax1DTSQh1EZ)
>
> When compiled

string TemplateStringOf(T...)()
if (T.length == 1)
{
     import std.traits : TemplateOf, TemplateArgsOf;
     import std.meta : AliasSeq, staticMap;
     import std.string : indexOf;
     import std.conv : text;
     static if (is(typeof({ alias a = TemplateOf!T; })))
     {
         alias Tmp = TemplateOf!T;
         alias Args = TemplateArgsOf!T;

         enum tmpFullName = Tmp.stringof;
         enum tmpName = tmpFullName[0..tmpFullName.indexOf('(')];

         alias AddCommas(T...) = AliasSeq!(T, ", ");
         alias ArgNames = staticMap!(.TemplateStringOf, Args);
         alias SeparatedArgNames = staticMap!(AddCommas, 
ArgNames)[0..$-1];

         return text(tmpName, "!(", SeparatedArgNames, ")");
     }
     else
     {
         return T[0].stringof;
     }
}

unittest {
     template A(T...) {}
     struct B {}
     struct D {}
     struct E {}
     template C(T...) {}

     assert(TemplateStringOf!(A!(B, C!(D, E))) == "A!(B, C!(D, 
E))");
}

unittest {
     template A(T) { template A(T) {} }

     assert(TemplateStringOf!(A!int) == "A!(int)");
}

Probably still some corner cases I haven't thought of, but it 
seems to cover what you're asking for.

One thing I didn't bother with is disambiguation - if B exists in 
modules foo and bar, the above will not specify which foo it's 
referring to. This is left as an exercise for the reader.

--
   Simen


More information about the Digitalmars-d mailing list