#include #include #include #include #include #include using namespace std; using namespace boost; /////////////////////////////////////////////////////////////////////////////// // exponentiation calculations template struct POWER_CORE : POWER_CORE{}; template struct POWER_CORE { enum : int { val = accum }; }; template struct POWER : POWER_CORE<1, base, exp>{}; /////////////////////////////////////////////////////////////////////////////// // # of digit calculations template struct NUM_DIGITS_CORE : NUM_DIGITS_CORE{}; template struct NUM_DIGITS_CORE { enum : int { val = depth}; }; template struct NUM_DIGITS : NUM_DIGITS_CORE<0, i>{}; template <> struct NUM_DIGITS<0> { enum : int { val = 1 }; }; /////////////////////////////////////////////////////////////////////////////// // Convert digit to character (1 -> '1') template struct DIGIT_TO_CHAR { enum : char{ val = i + 48 }; }; /////////////////////////////////////////////////////////////////////////////// // Find the digit at a given offset into a number of the form 0000000017 template // place -> [0 .. 10] struct DIGIT_AT { enum : char{ val = (i / POWER<10, place>::val) % 10 }; }; struct NULL_CHAR { enum : char{ val = '\0' }; }; /////////////////////////////////////////////////////////////////////////////// // Convert the digit at a given offset into a number of the form '0000000017' to a character template // place -> [0 .. 9] struct ALT_CHAR : DIGIT_TO_CHAR< DIGIT_AT::val >{}; /////////////////////////////////////////////////////////////////////////////// // Convert the digit at a given offset into a number of the form '17' to a character // Template description, with specialization to generate null characters for out of range offsets template struct OFFSET_CHAR_CORE_CHECKED{}; template struct OFFSET_CHAR_CORE_CHECKED : NULL_CHAR{}; template struct OFFSET_CHAR_CORE_CHECKED : ALT_CHAR{}; // Perform the range check and pass it on template struct OFFSET_CHAR_CORE : OFFSET_CHAR_CORE_CHECKED{}; // Calc the number of digits and pass it on template struct OFFSET_CHAR : OFFSET_CHAR_CORE::val>{}; /////////////////////////////////////////////////////////////////////////////// // Integer to char* template. Works on unsigned ints. template struct IntToStr { const static char str[]; typedef typename mpl::string< OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, /*OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val,*/ NULL_CHAR::val>::type type; }; template const char IntToStr::str[] = { OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, OFFSET_CHAR::val, NULL_CHAR::val }; template struct IF { typedef Then RET; }; template struct IF { typedef Else RET; }; template < typename Str1, typename Str2 > struct concat : mpl::insert_range::type, Str2> {}; template struct concat3 : mpl::insert_range::type, typename concat::type > {}; typedef typename mpl::string<'f','i','z','z'>::type fizz; typedef typename mpl::string<'b','u','z','z'>::type buzz; typedef typename mpl::string<'\r', '\n'>::type mpendl; typedef typename concat::type fizzbuzz; // discovered boost mpl limitation on some length template struct FizzBuzz { typedef typename concat3::type, typename IF::type >::RET >::RET >::RET, typename mpendl::type>::type type; }; template <> struct FizzBuzz<1> { typedef mpl::string<'1','\r','\n'>::type type; }; int main(int argc, char** argv) { const int n = 7; std::cout << mpl::c_str::type>::value << std::endl; return 0; }