How can i increase max number recursive template expansions?

John Colvin john.loughran.colvin at gmail.com
Sun Jul 7 13:22:39 PDT 2013


On Sunday, 7 July 2013 at 19:55:26 UTC, QAston wrote:
> I have a large enum in my code (opcodes for a protocol) - using 
> std.traits.EnumMembers gives me a recursive template error.
>
> How can i increase max number recursive template expansions?

I don't think you can. Please file a bug report: even though it 
might not get fixed any time soon (other than maybe just upping 
the threshold), there is talk of enabling more imperative-style 
programming in templates at the moment, and this would be a good 
case for it.

Try this as a workaround for now:

import std.typetuple;

template EnumMembersLarge(E)
     if (is(E == enum))
{
     // Supply the specified identifier to an constant value.
     template WithIdentifier(string ident)
     {
         static if (ident == "Symbolize")
         {
             template Symbolize(alias value)
             {
                 enum Symbolize = value;
             }
         }
         else
         {
             mixin("template Symbolize(alias "~ ident ~")"
                  ~"{"
                      ~"alias "~ ident ~" Symbolize;"
                  ~"}");
         }
     }

     template EnumSpecificMembers(names...)
     {
         static if (names.length > 0)
         {
             alias TypeTuple!(
                     WithIdentifier!(names[0])
                         .Symbolize!(__traits(getMember, E, 
names[0])),
                     EnumSpecificMembers!(names[1 .. $])
                 ) EnumSpecificMembers;
         }
         else
         {
             alias TypeTuple!() EnumSpecificMembers;
         }
     }

     alias TypeTuple!(EnumSpecificMembers!(__traits(allMembers, 
E)[0..$/2]),
                      EnumSpecificMembers!(__traits(allMembers, 
E)[$/2..$])
           EnumMembersLarge;
}

All except the last alias line and the changed name is just 
copied and pasted from EnumMembers.
As you can see we're doing the recursive template stuff in 2 
sections and then splicing them together, halving the recursion 
depth. The result is exactly equivalent to EnumMembers. If your 
enum is really huge you could split it up in to thirds or 
quarters, or even generate the split automatically with a 
template.


More information about the Digitalmars-d-learn mailing list