エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

Fizz Buzz by C++

分岐もループもなくして、めんどくさく解いてみる。

#include <iostream>

template<int N>
struct Fizz
{
    static const bool enabled = false;
    typedef Fizz<N + 1> next;
};

template<int N>
struct Buzz
{
    static const bool enabled = false;
    typedef Buzz<N + 1> next;
};

template<>
struct Fizz<3>
{
    static const bool enabled = true;
    typedef Fizz<1> next;
};

template<>
struct Buzz<5>
{
    static const bool enabled = true;
    typedef Buzz<1> next;
};

template<int N, bool FIZZ_ENABLED, bool BUZZ_ENABLED>
struct FizzBuzzWriter;

template<int N>
struct FizzBuzzWriter<N, false, false>
{
    static void write(std::ostream& out) { out << N << "\n"; }
};

template<int N>
struct FizzBuzzWriter<N, true, false>
{
    static void write(std::ostream& out) { out << "Fizz\n"; }
};

template<int N>
struct FizzBuzzWriter<N, false, true>
{
    static void write(std::ostream& out) { out << "Buzz\n"; }
};

template<int N>
struct FizzBuzzWriter<N, true, true>
{
    static void write(std::ostream& out) { out << "FizzBuzz\n"; }
};

template<int MAX, int N = 1, typename FIZZ = Fizz<N>, typename BUZZ = Buzz<N> >
struct FizzBuzz
{
    static void write(std::ostream& out)
    {
        FizzBuzzWriter<N, FIZZ::enabled, BUZZ::enabled>::write(out);
        FizzBuzz<MAX, N + 1, typename FIZZ::next, typename BUZZ::next>::write(out);
    }
};

template<int MAX, typename FIZZ, typename BUZZ>
struct FizzBuzz<MAX, MAX, FIZZ, BUZZ>
{
    static void write(std::ostream& out)
    {
        FizzBuzzWriter<MAX, FIZZ::enabled, BUZZ::enabled>::write(out);
    }
};

int main(int argc, char* argv[])
{
    FizzBuzz<30>::write(std::cout);

    return 0;
}