テンプレートでたらいまわし(4回目)
さらに高速化・簡単化できた。
#include <iostream> /* NullType */ class NullType; /* Typelist */ template <class T, class U> struct Typelist; /* Length */ template <class T> struct Length; template <> struct Length<NullType> { enum { value = 0 }; }; template <class T, class U> struct Length< Typelist<T, U> > { enum { value = 1 + Length<U>::value }; }; /* True */ class True; /* False */ class False; /* LessEq */ template <class T, class U> struct LessEq; template <> struct LessEq< NullType, NullType > { typedef True Result; }; template <class U1, class U2> struct LessEq< NullType, Typelist<U1, U2> > { typedef True Result; }; template <class T1, class T2> struct LessEq< Typelist<T1, T2>, NullType > { typedef False Result; }; template <class T1, class T2, class U1, class U2> struct LessEq< Typelist<T1, T2>, Typelist<U1, U2> > { typedef typename LessEq<T2, U2>::Result Result; }; /* Int */ template <int n> struct Int { typedef typename Int<n - 1>::Result TList; typedef Typelist< void, TList > Result; }; template <> struct Int<0> { typedef NullType Result; }; /* Tarai */ template <class T, int x, int y, int z> struct Tarai1; template <int x, int y, int z> struct Tarai { typedef typename Int<x>::Result X; typedef typename Int<y>::Result Y; typedef typename LessEq<X, Y>::Result B; enum { value = Tarai1<B, x, y, z>::value }; }; template <int x, int y, int z> struct Tarai1<True, x, y, z> { enum { value = y }; }; template <int x, int y, int z> struct Tarai1<False, x, y, z> { enum { xx = Tarai<x - 1, y, z>::value }; enum { yy = Tarai<y - 1, z, x>::value }; enum { zz = Tarai<z - 1, x, y>::value }; enum { value = Tarai<xx, yy, zz>::value }; }; int main(int argc, char *argv[]) { int n = Tarai<24, 12, 1>::value; std::cout << n << std::endl; return 0; }
- 実行結果
% time g++ tarai4.cpp real 0m2.907s user 0m2.776s sys 0m0.104s % time ./a.out 24 real 0m0.003s user 0m0.004s sys 0m0.000s