modを使わないFizzBuzz2 - wiseler : WAR IS PEACE
コンパイル時と実行時の合わせ技によるFizzBuzzをやられたので、純粋なコンパイル時FizzBuzzを書いてみることにする。
そもそもコンパイル時とは何か。それは、コンパイル時に1から100までの、どの値がFizzで、どの値がBuzzで、FizzBuzzで、あるいは数値で表示するかを計算してしまうことだ。だから実行時にすることは、既に計算された結果を表示するだけだ。
実行時に、あらかじめ計算しておこうとすると、100個の配列を用意して、そこに答えを格納することになるだろう。テンプレートメタプログラミングでは、型の配列、すなわちシークエンスを用いる。
#include <iostream>
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#define BOOST_MPL_LIMIT_VECTOR_SIZE 100
#include <boost/mpl/vector.hpp>
#include <boost/cstdint.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/for_each.hpp>
namespace mpl = boost::mpl ;
struct Fizz{ static char * const value ; } ;
struct Buzz{ static char * const value ; } ;
struct FizzBuzz{static char *const value ; } ;
char * const Fizz::value = "Fizz" ;
char * const Buzz::value = "Buzz" ;
char * const FizzBuzz::value = "FizzBuzz" ;
template<int i>
struct FizzBuzzSequence
{
typedef typename mpl::eval_if_c< (i % 3 == 0) && (i % 5 == 0), mpl::identity< FizzBuzz >
, mpl::eval_if_c< (i % 3 == 0), mpl::identity< Fizz >
, mpl::eval_if_c< (i % 5 == 0), mpl::identity< Buzz >, mpl::int_< i >
>
>
>::type value ;
typedef typename mpl::push_back<
typename FizzBuzzSequence< i - 1 >::type
, value
>::type type ;
} ;
template < >
struct FizzBuzzSequence<1>
{
typedef mpl::vector< mpl::int_<1> > type ;
} ;
struct print
{
template < typename T >
void operator () (T) const
{
std::cout << T::value << "\n" ;
}
} ;
int main()
{
mpl::for_each< FizzBuzzSequence<100>::type >( print() ) ;
}
美しい。何と単純明快なコードであることだろう。実はMPLのシークエンスを使うのは初めてだったのだが、とても簡単で楽しかった。MPLは神によって書かれたコードではなかろうか。
なお、実行には、Boost.MPLのvectorの要素数を100まで用意しないといけない。すなわち、boost/mpl/vector以下に、vector60.hppからvector100.hppまでを用意する必要がある。といっても中身は単純だ。一部を単純に置き換えるだけで、後はすべてプリプロセッサメタプログラミングがやってくれる。
また当然だが、かなり規格準拠度の高いC++コンパイラが要求される。
拝見しました。すごい! boost::mplでこんなにすっきりするのですね。
ReplyDeleteただ問題はコンパイルで、やはり、自分の環境(VisualStudio2005)ですとコンパイル中にエラー落ちしてしまいました…。2008だとうまくいくと思いますので、他日、詳しく見てみたいと思います。
# まさかこんなのまでCompile-Timeでいけるとは、C++は変態ですね(ほめ言葉)