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.