#include <iostream>
template <char N>
struct CharToStringHolder
{
const char data[4];
constexpr inline CharToStringHolder()
: data({N / 100 + 48, N / 10 + 48, N % 10 + 48, 0}) {}
};
template <char N>
constexpr const char* char_to_string()
{
return CharToStringHolder<N>().data;
}
template <char N>
constexpr const char* fizzbuzz()
{
return ( ( N % 3 == 0 && N % 5 == 0 ) ? "FizzBuzz"
: ( ( N % 3 == 0 ) ? "Fizz"
: ( ( N % 5 == 0 ) ? "Buzz"
: char_to_string<N>() )));
}
template<const char*... args>
struct CompileTimeArray
{
static const char* data[sizeof...(args)];
};
template<const char*... args>
const char* CompileTimeArray<args...>::data[sizeof...(args)] = { args... };
template<size_t N, template<size_t> class MetaFunc, const char*... args>
struct generate_array_impl
{
typedef typename generate_array_impl<N-1, MetaFunc, MetaFunc<N>::value, args...>::result result;
};
template<template<size_t> class MetaFunc, const char*... args>
struct generate_array_impl<0, MetaFunc, args...>
{
typedef CompileTimeArray<MetaFunc<0>::value, args...> result;
};
template<size_t N, template<size_t> class MetaFunc>
struct GenerateArray
{
typedef typename generate_array_impl<N-1, MetaFunc>::result result;
};
template<size_t index>
struct FizzBuzzMetaFunc
{
static const char value[sizeof(fizzbuzz<index>())];
};
template<size_t index>
const char FizzBuzzMetaFunc<index>::value[sizeof(fizzbuzz<index>())] = {fizzbuzz<index>()};
int main(void)
{
const size_t count = 100;
typedef typename GenerateArray<count, FizzBuzzMetaFunc>::result A;
for(size_t i = 0; i < count; ++i)
{
std::cout << A::data[i] << "\n";
}
return 0;
}