/* How to "fly" when dealing with type size > 900 without changing
 * the template instantiation depth.
 * Convention: 'fault index' is the numerical value in the compiler error 
 *             message 'struct GetSize<480>', here fault index = 480.
 *             'min. fault index' is the first compilation error due to 
 *             template instantiation.
 * 
 * 1st: evaluate the min. fault index (a) with a bigger step size 
 *      (e.g. GETSIZE_STEP = 500)
 *          #define GETSIZE_TYPE Fruit
 *          #define GETSIZE_STEP 500
 *          #include "getsize.hpp"
 * 
 *      (a) possible results
 *        - min. fault index = 1: step size too big (exception: if step size = 1 
 *          the min. fault index is the required type size)
 *        - no compilation errors due to template instantiation:
 *          step size too small
 * 
 * 2nd: evaluate the type size, offset = min. fault index * bigger step size - 1
 *      (e.g. min. fault index = 480, GETSIZE_OFFSET = 480 * 500 - 1) and 
 *      GETSIZE_STEP = 1
 *          #define GETSIZE_TYPE Fruit
 *      //    #define GETSIZE_STEP 500
 *          #define GETSIZE_OFFSET (480 * 500 - 1)
 *          #include "getsize.hpp"
 * 
 *      min. fault index is the required type size (e.g. 240024 = 480 * 500 + 24)
 * 
 * P.S. type size > 810000 (900 * 900) requires step size > 900
 *      it gets a little tricky ;-)
 */

#ifdef GETSIZE_TYPE

#ifndef GETSIZE_STEP
#define GETSIZE_STEP	1
#endif	// GETSIZE_STEP

#ifndef GETSIZE_OFFSET
#define GETSIZE_OFFSET	0
#endif	// GETSIZE_OFFSET

template <int n> 
struct GetSize { 
	enum { value = 1 + GetSize<n-1>::value };
	typedef int test_array[static_cast<int>(sizeof(GETSIZE_TYPE)) \
		- GETSIZE_STEP - value * GETSIZE_STEP];
};

template <> 
struct GetSize<GETSIZE_OFFSET> { 
	enum { value = GETSIZE_OFFSET };
	typedef int test_array[1];
};

#define TEMPLATE_INSTANTIATION_DEPTH	900	// default value of GNU C++11
enum { template_instantiation = \
	GetSize<GETSIZE_OFFSET + TEMPLATE_INSTANTIATION_DEPTH>::value };

#endif	// GETSIZE_TYPE