1. #include <iostream>
  2.  
  3. const char FIZZ = 1;
  4. const char BUZZ = 2;
  5. const char FIZZBUZZ = 3;
  6. const char NONE = 0;
  7.  
  8. template<char Flag, unsigned Index>
  9. struct FBResult;
  10.  
  11. // FIZZ
  12. template<unsigned Index> struct FBResult<FIZZ, Index>
  13. {
  14.   enum { size = 5 };
  15.   static const char data[size];
  16. };
  17. template<unsigned Index>
  18. const char FBResult<FIZZ, Index>::data[FBResult<FIZZ, Index>::size] = { 'F','i','z','z','\n' };
  19.  
  20. // BUZZ
  21. template<unsigned Index> struct FBResult<BUZZ, Index>
  22. {
  23.   enum { size = 5 };
  24.   static const char data[size];
  25. };
  26. template<unsigned Index>
  27. const char FBResult<BUZZ, Index>::data[FBResult<BUZZ, Index>::size] = { 'B','u','z','z','\n' };
  28.  
  29. // FIZZBUZZ
  30. template<unsigned Index> struct FBResult<FIZZBUZZ, Index>
  31. {
  32.   enum { size = 9 };
  33.   static const char data[size];
  34. };
  35. template<unsigned Index>
  36. const char FBResult<FIZZBUZZ, Index>::data[FBResult<FIZZBUZZ, Index>::size] = { 'F','i','z','z','B','u','z','z','\n' };
  37.  
  38. // NUMBER
  39. template<unsigned Index> struct FBResult<NONE, Index>
  40. {
  41.   enum { size = 5 };
  42.   static const char data[size];
  43. };
  44. template<unsigned Index>
  45. const char FBResult<NONE, Index>::data[FBResult<NONE, Index>::size] = { Index/1000 + 48, (Index%1000)/100 + 48, (Index%100)/10 + 48, (Index%10) + 48, '\n' };
  46.  
  47. // this sets value to a flag value of either 1, 2, 3, or 0,
  48. // determining whether to print fizz, buzz, fizzbuzz, or number
  49. template <unsigned N> struct FizzFlag
  50. {
  51.   enum { value = (0x0000 | ((N % 3 == 0) * FIZZ) | ((N % 5 == 0) * BUZZ)) };
  52. };
  53.  
  54. template<unsigned N, unsigned c> struct FizzBuzzChar
  55. {
  56.   enum { value = FBResult<FizzFlag<N>::value, N>::data[c] };
  57. };
  58.  
  59. template<unsigned N>
  60. struct FizzStringSize
  61. {
  62.   enum { value = FBResult<FizzFlag<N>::value, N>::size };
  63. };
  64.  
  65. template<char... args>
  66. struct CompileTimeArray
  67. {
  68.   static const char data[sizeof...(args)];
  69. };
  70. template <char... args>
  71. const char CompileTimeArray<args...>::data[sizeof...(args)] = {args...};
  72.  
  73. template<unsigned C, unsigned N, char... args>
  74. struct generate_array_impl
  75. {
  76.   typedef typename generate_array_impl<C-1, N, FizzBuzzChar<N,C>::value, args...>::result result;
  77. };
  78.  
  79. template<unsigned N, char... args>
  80. struct generate_array_impl<0, N, args...>
  81. {
  82.   typedef typename generate_array_impl<FizzStringSize<N-1>::value - 1, N-1, FizzBuzzChar<N,0>::value, args...>::result result;
  83. };
  84.  
  85. template<char... args>
  86. struct generate_array_impl<0, 1, args...>
  87. {
  88.   typedef CompileTimeArray< FizzBuzzChar<1,0>::value, args...> result;
  89. };
  90.  
  91. template<unsigned N>
  92. struct GenerateFizzBuzzArray
  93. {
  94.   typedef typename generate_array_impl<FizzStringSize<N-1>::value - 1, N-1, '\0'>::result result;
  95. };
  96.  
  97. int main(void)
  98. {
  99.   const unsigned count = 100;
  100.   typedef GenerateFizzBuzzArray<count>::result A;
  101.  
  102.   std::cout << A::data;
  103.  
  104.   return 0;
  105. }