Templateのお勉強がてらFizzBuzz

```
int main() { return 0; }

#include <iostream>

#pragma mark Definition: Boolean

struct True { };
struct False { };

#pragma mark Definition: Equality

namespace {
	template <typename, typename>
	struct eq_impl { using type = False; };

	template <typename A>
	struct eq_impl<A, A> { using type = True; };
};

template <typename A, typename B>
using Equal = typename eq_impl<A, B>::type;

#pragma mark Definition: Natural Number

struct Zero {};
template <typename>
struct S {};

template <typename>
struct Eval;

template <>
struct Eval<Zero> {
	static constexpr int value = 0;
};
template <typename Num>
struct Eval<S<Num>> {
	static constexpr int value = 1 + Eval<Num>::value;
};

std::ostream &operator<<(std::ostream &os, const Zero &) {
	os << Eval<Zero>::value;
	return os;
}

template <typename Num>
std::ostream &operator<<(std::ostream &os, const S<Num> &) {
	os << Eval<S<Num>>::value;
	return os;
}

#pragma mark Definition: If

namespace {
	template <typename Condition, typename Then, typename Else>
	struct if_impl;

	template <typename Then, typename Else>
	struct if_impl<True, Then, Else> {
		using type = Then;
	};

	template <typename Then, typename Else>
	struct if_impl<False, Then, Else> {
		using type = Else;
	};
};

template <typename Condition, typename Then, typename Else>
using If = typename if_impl<Condition, Then, Else>::type;

#pragma mark Definition: Or

namespace {
	template <typename, typename>
	struct or_impl {
		using type = True;
	};

	template <>
	struct or_impl<False, False> {
		using type = False;
	};
};

template <typename P, typename Q>
using Or = typename or_impl<P, Q>::type;

#pragma mark Utility

namespace {
	template <int n>
	struct make_num_impl {
		using type = S<typename make_num_impl<n - 1>::type>;
	};

	template <>
	struct make_num_impl<0> {
		using type = Zero;
	};
};

template <int n>
using MakeNum = typename make_num_impl<n>::type;

struct Stop {};

struct Nothing {};
std::ostream &operator<<(std::ostream &os, const Nothing *) { return os; };

struct LineBreak { LineBreak() { std::cout << std::endl; } };

template <typename X, typename Y, typename T>
using Enable = If<Equal<X, Y>, Stop, T>;

#pragma mark Implementation of Fizz / Buzz

#define DefineFizzBuzz(Name, ...)\
template <typename Num, typename C = Zero> struct Name;\
template <typename Num, typename C> struct Name<S<Num>, C> : public Name<Num, If<Equal<C, __VA_ARGS__>, Zero, S<C>>> {};\
template <typename C> struct Name<Zero, C> { using is_enable = Equal<C, Zero>;\
	Name() { std::cout << static_cast<If<is_enable, Name, Nothing> *>(nullptr); };\
};\
template <typename Num, typename C> std::ostream &operator<<(std::ostream &os, const Name<Num, C> *) {\
	os << #Name;\
	return os;\
};

DefineFizzBuzz(Fizz, S<S<Zero>>);
DefineFizzBuzz(Buzz, S<S<S<S<Zero>>>>);

#pragma mark Implementation of Number

template <typename> struct number_impl;

template <typename Num>
struct number_impl {
	number_impl() { std::cout << Num(); }
};

template <typename Num>
using Number = If<Or<typename Fizz<Num>::is_enable, typename Buzz<Num>::is_enable>, Nothing, number_impl<Num>>;

#pragma mark FizzBuzz Composition
 
template <typename Num, typename Max>
struct fizz_buzz_impl : public
  Fizz<Num>
, Buzz<Num>
, Number<Num>
, LineBreak
, Enable<Num, Max, fizz_buzz_impl<S<Num>, Max>> { };

template <int n>
using FizzBuzz = fizz_buzz_impl<S<Zero>, MakeNum<n>>;

FizzBuzz<100> fizzbuzz;
```

[wandbox](http://melpon.org/wandbox/permlink/8eXSZ2SivG8mKe1O)

~~(_ideoneのC++4.9.2とかC++14だと動かない！_)~~
[ideone](http://ideone.com/QCPHae)
(`FizzBuzz<100>` だと動かないけど `FizzBuzz<20>` くらいなら動いた)