読者です 読者をやめる 読者になる 読者になる

type_traits と tuple を使ってコンパイル時 FizzBuzz

C++
#include <iostream>
#include <type_traits>
#include <tuple>

struct fizz{ static char const value[ ]; };
char const fizz::value[ ] = "fizz";

struct buzz{ static char const value[ ]; };
char const buzz::value[ ] = "buzz";

struct fizzbuzz{ static char const value[ ]; };
char const fizzbuzz::value[ ] = "fizzbuzz";

template< std::size_t I >
struct num{ static std::size_t const value = I; };



template< std::size_t I >
using fizzbuzz_val = std::conditional< I % 15 == 0, fizzbuzz,
                                    typename std::conditional< I % 3 == 0, fizz,
                                        typename std::conditional< I % 5 == 0, buzz, 
                                            num<I>
                                        >::type
                                    >::type
                                >;



template< class T, class U>
struct append;

template< class... Args, class T >
struct append< std::tuple<Args...>, T >{
    typedef std::tuple< Args..., T > type;
};



template< std::size_t I >
struct fizzbuzz_seq{
    typedef typename append< typename fizzbuzz_seq<I-1>::type,
                             typename fizzbuzz_val<I>::type
                           >::type type;
};

template<>
struct fizzbuzz_seq<1>{
    typedef std::tuple<num<1>> type;
};



template< class T >
struct print_tuple_values;

template< class T, class... Args >
struct print_tuple_values<std::tuple<T, Args...>>{
    void operator()() const
    {
        std::cout << T::value << '\n';
        print_tuple_values<std::tuple<Args...>>()();
    }
};

template< class T >
struct print_tuple_values<std::tuple<T>>{
    void operator()() const
    {
        std::cout << T::value << '\n';
    }
};



int main()
{
    typedef typename fizzbuzz_seq<100>::type result;
    print_tuple_values<result>()();
    return 0;
}