Advertisement
Guest User

vissi

a guest
Jan 14th, 2011
11,738
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.41 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <cstdlib>
  4. #include <boost/mpl/string.hpp>
  5. #include <boost/mpl/fold.hpp>
  6. #include <boost/mpl/size_t.hpp>
  7.  
  8. using namespace std;
  9. using namespace boost;
  10.  
  11. ///////////////////////////////////////////////////////////////////////////////
  12. // exponentiation calculations
  13. template <int accum, int base, int exp> struct POWER_CORE : POWER_CORE<accum * base, base, exp - 1>{};
  14.  
  15. template <int accum, int base>
  16. struct POWER_CORE<accum, base, 0>
  17. {
  18.     enum : int { val = accum };
  19. };
  20.  
  21. template <int base, int exp> struct POWER : POWER_CORE<1, base, exp>{};
  22.  
  23. ///////////////////////////////////////////////////////////////////////////////
  24. // # of digit calculations
  25. template <int depth, unsigned int i> struct NUM_DIGITS_CORE : NUM_DIGITS_CORE<depth + 1, i / 10>{};
  26.  
  27. template <int depth>
  28. struct NUM_DIGITS_CORE<depth, 0>
  29. {
  30.     enum : int { val = depth};
  31. };
  32.  
  33. template <int i> struct NUM_DIGITS : NUM_DIGITS_CORE<0, i>{};
  34.  
  35. template <>
  36. struct NUM_DIGITS<0>
  37. {
  38.     enum : int { val = 1 };
  39. };
  40.  
  41. ///////////////////////////////////////////////////////////////////////////////
  42. // Convert digit to character (1 -> '1')
  43. template <int i>
  44. struct DIGIT_TO_CHAR
  45. {
  46.     enum : char{ val = i + 48 };
  47. };
  48.  
  49. ///////////////////////////////////////////////////////////////////////////////
  50. // Find the digit at a given offset into a number of the form 0000000017
  51. template <unsigned int i, int place> // place -> [0 .. 10]
  52. struct DIGIT_AT
  53. {
  54.     enum : char{ val = (i / POWER<10, place>::val) % 10 };
  55. };
  56.  
  57. struct NULL_CHAR
  58. {
  59.     enum : char{ val = '\0' };
  60. };
  61.  
  62. ///////////////////////////////////////////////////////////////////////////////
  63. // Convert the digit at a given offset into a number of the form '0000000017' to a character
  64. template <unsigned int i, int place> // place -> [0 .. 9]
  65.     struct ALT_CHAR : DIGIT_TO_CHAR< DIGIT_AT<i, place>::val >{};
  66.  
  67. ///////////////////////////////////////////////////////////////////////////////
  68. // Convert the digit at a given offset into a number of the form '17' to a character
  69.  
  70. // Template description, with specialization to generate null characters for out of range offsets
  71. template <unsigned int i, int offset, int numDigits, bool inRange>  
  72.     struct OFFSET_CHAR_CORE_CHECKED{};
  73. template <unsigned int i, int offset, int numDigits>                
  74.     struct OFFSET_CHAR_CORE_CHECKED<i, offset, numDigits, false> : NULL_CHAR{};
  75. template <unsigned int i, int offset, int numDigits>                
  76.     struct OFFSET_CHAR_CORE_CHECKED<i, offset, numDigits, true>  : ALT_CHAR<i, (numDigits - offset) - 1 >{};
  77.  
  78. // Perform the range check and pass it on
  79. template <unsigned int i, int offset, int numDigits>
  80.     struct OFFSET_CHAR_CORE : OFFSET_CHAR_CORE_CHECKED<i, offset, numDigits, offset < numDigits>{};
  81.  
  82. // Calc the number of digits and pass it on
  83. template <unsigned int i, int offset>
  84.     struct OFFSET_CHAR : OFFSET_CHAR_CORE<i, offset, NUM_DIGITS<i>::val>{};
  85.  
  86. ///////////////////////////////////////////////////////////////////////////////
  87. // Integer to char* template. Works on unsigned ints.
  88. template <unsigned int i>
  89. struct IntToStr
  90. {
  91.     const static char str[];
  92.     typedef typename mpl::string<
  93.     OFFSET_CHAR<i, 0>::val,
  94.     OFFSET_CHAR<i, 1>::val,
  95.     OFFSET_CHAR<i, 2>::val,
  96.     OFFSET_CHAR<i, 3>::val,
  97.     OFFSET_CHAR<i, 4>::val,
  98.     OFFSET_CHAR<i, 5>::val,
  99.     /*OFFSET_CHAR<i, 6>::val,
  100.     OFFSET_CHAR<i, 7>::val,
  101.     OFFSET_CHAR<i, 8>::val,
  102.     OFFSET_CHAR<i, 9>::val,*/
  103.     NULL_CHAR::val>::type type;
  104. };
  105.  
  106. template <unsigned int i>
  107. const char IntToStr<i>::str[] =
  108. {
  109.     OFFSET_CHAR<i, 0>::val,
  110.     OFFSET_CHAR<i, 1>::val,
  111.     OFFSET_CHAR<i, 2>::val,
  112.     OFFSET_CHAR<i, 3>::val,
  113.     OFFSET_CHAR<i, 4>::val,
  114.     OFFSET_CHAR<i, 5>::val,
  115.     OFFSET_CHAR<i, 6>::val,
  116.     OFFSET_CHAR<i, 7>::val,
  117.     OFFSET_CHAR<i, 8>::val,
  118.     OFFSET_CHAR<i, 9>::val,
  119.     NULL_CHAR::val
  120. };
  121.  
  122. template <bool condition, class Then, class Else>
  123. struct IF
  124. {
  125.     typedef Then RET;
  126. };
  127.  
  128. template <class Then, class Else>
  129. struct IF<false, Then, Else>
  130. {
  131.     typedef Else RET;
  132. };
  133.  
  134.  
  135. template < typename Str1, typename Str2 >
  136. struct concat : mpl::insert_range<Str1, typename mpl::end<Str1>::type, Str2> {};
  137. template <typename Str1, typename Str2, typename Str3 >
  138. struct concat3 : mpl::insert_range<Str1, typename mpl::end<Str1>::type, typename concat<Str2, Str3 >::type > {};
  139.  
  140. typedef typename mpl::string<'f','i','z','z'>::type fizz;
  141. typedef typename mpl::string<'b','u','z','z'>::type buzz;
  142. typedef typename mpl::string<'\r', '\n'>::type mpendl;
  143. typedef typename concat<fizz, buzz>::type fizzbuzz;
  144.  
  145. // discovered boost mpl limitation on some length
  146.  
  147. template <int N>
  148. struct FizzBuzz
  149. {
  150.     typedef typename concat3<typename FizzBuzz<N - 1>::type, typename IF<N % 15 == 0, typename fizzbuzz::type, typename IF<N % 3 == 0, typename fizz::type, typename IF<N % 5 == 0, typename buzz::type, typename IntToStr<N>::type >::RET >::RET >::RET, typename mpendl::type>::type type;
  151.     //typedef typename concat<typename FizzBuzz<N - 1>::type, typename IF<N % 15 == 0, typename fizzbuzz::type, typename IF<N % 3 == 0, typename fizz::type, typename IF<N % 5 == 0, typename buzz::type, typename IntToStr<N>::type >::RET >::RET >::RET>::type type;
  152. };
  153.  
  154. template <>
  155. struct FizzBuzz<1>
  156. {
  157.     typedef mpl::string<'1','\r','\n'>::type type;
  158. };
  159.  
  160. int main(int argc, char** argv)
  161. {
  162.     std::cout << mpl::c_str<FizzBuzz<8>::type>::value << std::endl;
  163.     return 0;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement