/*
This value is set, by default to the max it can be set to avoid
template instatiation depth greater than 17 when not used inside
templates. 17 comes from the standard , Annex B.2, the second 
bullet from the end.
This is only a recommendation, and implemenations are free to 
define almost anything as such. GCC uses 500 by default, but this
can be set with the -ftemplate-depth flag. (That was, in fact, 
how this was tested to work for 17). EDG based compilers (Comeau,
Intel) default to 60.
*/
const unsigned limit = 15;//475+

//Not a template to further reduce both clutter and depth issues
//Also can be used when constant can be used at preprocess time
//c_pow<x>::val is used when decisions must be delayed until 
// instantiation time
const unsigned l_0 = 1;
const unsigned l_1 = limit * l_0;
const unsigned l_2 = limit * l_1;
const unsigned l_3 = limit * l_2;
const unsigned l_4 = limit * l_3;
const unsigned l_5 = limit * l_4;
const unsigned l_6 = limit * l_5;

template<unsigned N, unsigned PLACE>
struct aval {};

//reduces instantiation depth issues
#define makeaval(x)					\
  template<unsigned N>					\
  struct aval<N,x> {					\
    static const unsigned val = (N/l_ ## x) % limit;	\
  }

makeaval(0);
makeaval(1);
makeaval(2);
makeaval(3);
makeaval(4);
makeaval(5);
makeaval(6);

template <unsigned N>
struct c_pow {};

#define makepow(x)				\
  template<>					\
  struct c_pow<x> {				\
    static const unsigned val = l_ ## x;	\
  }

makepow(0);
makepow(1);
makepow(2);
makepow(3);
makepow(4);
makepow(5);
makepow(6);

struct empty {};

template<bool P,
         class T,
	 template<unsigned, unsigned> class F,
	 unsigned N,
	 unsigned PLACE>
struct c_if {
	   typedef T type;
	 };

template<class T,
	 template<unsigned, unsigned> class F,
         unsigned N,
         unsigned PLACE>
struct c_if<false,T,F,N,PLACE> {
           typedef F<N,PLACE> type;
         };

//our wrap parameter N can be represented as a polynomial
// a_n * limit^n for n starting at 0.  
//We will assume a limit of 10 here, for ease of notation.
//we will use 999 as an example number.
//999,0 inherits from every n,0 such that n < 999
//999,1 inherits from 990,1
//990,1 inherits from every n,1 such that n < 990 and 10 divides n
//999,2 inherits from 900
//900,2 inherits from every n,2 such that n < 900 and 100 divides n
//9,1 inherits from empty
#define MAKECOUNT							\
  template <unsigned N, unsigned PLACE>					\
  struct wrap : public c_if<(N / c_pow<PLACE>::val) == 0,		\
			    empty,					\
			    wrap,					\
			    (PLACE == 0) ?				\
			    N-1 :					\
			     ((aval<N,((PLACE == 0) ? 0 : PLACE-1) >::val == 0) ? \
			      (N - c_pow<PLACE>::val) :			\
			      (aval<N,PLACE>::val * c_pow<PLACE>::val)), \
			    PLACE>::type {				\
    static const wrap * pass;						\
  };									\
  template<unsigned PLACE>						\
  char (*test(const wrap<0,PLACE> * ))[1]

MAKECOUNT;

const unsigned DEDUCT = 1;

#define GET6 0
#define GET5 ((sizeof *test(wrap<GET6 + l_6 - 1,5>::pass))-DEDUCT)
#define GET4 ((sizeof *test(wrap<GET5 + l_5 - 1,4>::pass))-DEDUCT)
#define GET3 ((sizeof *test(wrap<GET4 + l_4 - 1,3>::pass))-DEDUCT)
#define GET2 ((sizeof *test(wrap<GET3 + l_3 - 1,2>::pass))-DEDUCT)
#define GET1 ((sizeof *test(wrap<GET2 + l_2 - 1,1>::pass))-DEDUCT)
#define GET0 ((sizeof *test(wrap<GET1 + l_1 - 1,0>::pass))-DEDUCT)

#define GET GET0

#define GET_S ((sizeof *test(wrap<GET+1,0>::pass)) -DEDUCT)
#define ISLIMIT(x) ((GET_S % l_ ## x) == 0)

#define OVER(x) \
char (*test(const wrap<GET + 1 - (ISLIMIT(x) ? 1 : 2),x> *))[GET + 1 - (ISLIMIT(x) ? 0 : 1) + DEDUCT]

#define SET						\
  char (*test(const wrap<GET+1,0> *))[GET+1+DEDUCT];	\
  OVER(1);						\
  OVER(2);						\
  OVER(3);						\
  OVER(4);						\
  OVER(5)

