Re: How can i increase max number recursive template expansions?

2013-07-10 Thread Ellery Newcomer

On 07/07/2013 01:22 PM, John Colvin wrote:

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.



or feel free to commandeer this one

http://d.puremagic.com/issues/show_bug.cgi?id=6471



Re: How can i increase max number recursive template expansions?

2013-07-08 Thread bearophile

Simen Kjaeraas:


However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:


Worth putting in Phobos?

Bye,
bearophile


Re: How can i increase max number recursive template expansions?

2013-07-08 Thread John Colvin

On Monday, 8 July 2013 at 09:03:24 UTC, bearophile wrote:

Simen Kjaeraas:


However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:


Worth putting in Phobos?

Bye,
bearophile


I reckon so. It's rare to have such huge structs or classes that 
this sort of this becomes a problem for them, but massive enums 
are reasonably common.


Re: How can i increase max number recursive template expansions?

2013-07-08 Thread Simen Kjaeraas

On 2013-07-08, 11:03, bearophile wrote:


Simen Kjaeraas:


However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:


Worth putting in Phobos?


Filed:

http://d.puremagic.com/issues/show_bug.cgi?id=10569

And created a pull request:

https://github.com/D-Programming-Language/phobos/pull/1400

--
Simen


How can i increase max number recursive template expansions?

2013-07-07 Thread QAston
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?


Re: How can i increase max number recursive template expansions?

2013-07-07 Thread Simen Kjaeraas

On 2013-07-07, 21:55, 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?


You can't. However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:



import std.typetuple;

template EnumMembers(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  200)
{
alias TypeTuple!(
EnumSpecificMembers!(names[0..$/2]),
EnumSpecificMembers!(names[$/2..$]),
) EnumSpecificMembers;
}
else 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 EnumSpecificMembers!(__traits(allMembers, E)) EnumMembers;
}



Here, this line:
static if (names.length  200)
uses divide-and-conquer to reduce the number of template instantiations.

--
Simen


Re: How can i increase max number recursive template expansions?

2013-07-07 Thread John Colvin

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.


Re: How can i increase max number recursive template expansions?

2013-07-07 Thread John Colvin

On Sunday, 7 July 2013 at 20:22:59 UTC, Simen Kjaeraas wrote:

On 2013-07-07, 21:55, 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?


You can't. However, you can amend std.traits.EnumMembers to work
with larger enums by using this version:



import std.typetuple;

template EnumMembers(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  200)
{
alias TypeTuple!(
EnumSpecificMembers!(names[0..$/2]),
EnumSpecificMembers!(names[$/2..$]),
) EnumSpecificMembers;
}
else 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 EnumSpecificMembers!(__traits(allMembers, E)) 
EnumMembers;

}



Here, this line:
static if (names.length  200)
uses divide-and-conquer to reduce the number of template 
instantiations.


We came up with almost identical solutions, posted within 19 
seconds of each other!


Re: How can i increase max number recursive template expansions?

2013-07-07 Thread John Colvin

On Sunday, 7 July 2013 at 20:41:17 UTC, Simen Kjaeraas wrote:

On 2013-07-07, 22:28, John Colvin wrote:

We came up with almost identical solutions, posted within 19 
seconds of each other!


Sorta. Mine does repeated halving, and makes DMD run out of 
memory with
16384 enum members. Yours balks at an enum of  about 1000 
elements.


so it does. Yup, yours is betters.


Re: How can i increase max number recursive template expansions?

2013-07-07 Thread QAston

On Sunday, 7 July 2013 at 20:28:12 UTC, John Colvin wrote:

On Sunday, 7 July 2013 at 20:22:59 UTC, Simen Kjaeraas wrote:

On 2013-07-07, 21:55, 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?


You can't. However, you can amend std.traits.EnumMembers to 
work

with larger enums by using this version:



import std.typetuple;

template EnumMembers(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  200)
   {
   alias TypeTuple!(
   EnumSpecificMembers!(names[0..$/2]),
   EnumSpecificMembers!(names[$/2..$]),
   ) EnumSpecificMembers;
   }
   else 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 EnumSpecificMembers!(__traits(allMembers, E)) 
EnumMembers;

}



Here, this line:
   static if (names.length  200)
uses divide-and-conquer to reduce the number of template 
instantiations.


We came up with almost identical solutions, posted within 19 
seconds of each other!


Thanks guys, you're awesome!