コンパイル時 FizzBuzz
なんか Twitter で話題になっていたので、Boost.MPL を使った FizzBuzz でも。
mpl::print を使用して、コンパイル時に出力も行います。
[ソース]
#include <boost/mpl/int.hpp> #include <boost/mpl/modulus.hpp> #include <boost/mpl/equal_to.hpp> #include <boost/mpl/and.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/print.hpp> #include <boost/mpl/vector_c.hpp> namespace mpl = boost::mpl; typedef mpl::equal_to< mpl::modulus<mpl::_1, mpl::int_<3> >, mpl::int_<0> > is_fizz; typedef mpl::equal_to< mpl::modulus<mpl::_1, mpl::int_<5> >, mpl::int_<0> > is_buzz; typedef mpl::and_<is_fizz, is_buzz> is_fizz_buzz; struct Fizz; struct Buzz; struct FizzBuzz; typedef mpl::lambda< mpl::if_< is_fizz_buzz, FizzBuzz, mpl::if_< is_fizz, Fizz, mpl::if_< is_buzz, Buzz, mpl::_1 > > > >::type fizz_buzz; typedef mpl::transform< mpl::vector_c<int, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 >, fizz_buzz > result; typedef mpl::print<result::type>::type disp; int main(){}
[出力]
|| main.cpp \boost\boost_1_47_0\boost\mpl\print.hpp|51 warning 4308| 負の整数定数が符号なしの型に変換されました。 main.cpp|56| コンパイルされたクラスの テンプレート のインスタンス化 'boost::mpl::print<T>' の参照を確認してください || with || [ || T=boost::mpl::vector20<boost::mpl::integral_c<int,1>,boost::mpl::integral_c<int,2>,Fizz,boost::mpl::integral_c<int,4>,Buzz,Fizz,boost::mpl::integral_c<int,7>,boost::mpl::integral_c<int,8>,Fizz,Buzz,boost::mpl::integral_c<int,11>,Fizz,boost::mpl::integral_c<int,13>,boost::mpl::integral_c<int,14>,FizzBuzz,boost::mpl::integral_c<int,16>,boost::mpl::integral_c<int,17>,Fizz,boost::mpl::integral_c<int,19>,Buzz> || ]
[おまけ]
普通に書いてみたらこんな感じになった。
[ソース]
#include <iostream> #include <string> #include <boost/variant.hpp> #include <boost/range/irange.hpp> #include <boost/range/adaptor/transformed.hpp> #include <boost/range/algorithm/for_each.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lexical_cast.hpp> struct to_fizzbuzz{ typedef std::string result_type; template<typename T> result_type operator ()(T n) const{ return n % 15 == 0 ? "FizzBuzz" : n % 3 == 0 ? "Fizz" : n % 5 == 0 ? "Buzz" : boost::lexical_cast<std::string>(n); } }; int main(){ using boost::adaptors::transformed; using boost::lambda::_1; int size = 100; boost::for_each( boost::irange(1, size)|transformed(to_fizzbuzz()), std::cout << _1 << "," ); return 0; }
うーむ、面白みが不足している。