Boost.MPL で FibBuzz
ついカッとなってやった。反省はしていない。
[ソース]
#define BOOST_MPL_LIMIT_VECTOR_SIZE 40 #include <boost/type_traits/is_same.hpp> #include <boost/mpl/assert.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/long.hpp> #include <boost/mpl/equal_to.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/minus.hpp> #include <boost/mpl/modulus.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/transform_view.hpp> #include <boost/mpl/range_c.hpp> #include <boost/mpl/identity.hpp> #include <boost/mpl/print.hpp> #include <boost/mpl/back_inserter.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/copy.hpp> namespace mpl = boost::mpl; template<typename N> struct fibonacci; template<typename N> struct fibonacci : mpl::eval_if< mpl::equal_to<N, mpl::long_<0> >, mpl::long_<0>, mpl::if_< mpl::equal_to<N, mpl::long_<1> >, mpl::long_<1>, mpl::plus< fibonacci<typename mpl::minus<N, mpl::long_<1> >::type>, fibonacci<typename mpl::minus<N, mpl::long_<2> >::type> > > >::type {}; struct Fizz : mpl::identity<Fizz>{}; struct Buzz : mpl::identity<Buzz>{}; struct FizzBuzz : mpl::identity<FizzBuzz>{}; template<typename N> struct to_fissbuzz : mpl::eval_if< mpl::equal_to<mpl::modulus<N, mpl::long_<15> >, mpl::long_<0> >, FizzBuzz, mpl::eval_if< mpl::equal_to<mpl::modulus<N, mpl::long_<3> >, mpl::long_<0> >, Fizz, mpl::eval_if< mpl::equal_to<mpl::modulus<N, mpl::long_<5> >, mpl::long_<0> >, Buzz, N > > >::type {}; typedef mpl::range_c<long, 1, 41> seq; typedef mpl::copy< mpl::transform_view< mpl::transform_view< seq, fibonacci<mpl::_1> >::type, to_fissbuzz<mpl::_1> >, mpl::back_inserter<mpl::vector<> > > result; typedef mpl::print<result::type>::type disp; int main(){}
[出力]
|| main.cpp || D:/compiletime/main.cpp : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。 \boost\boost_1_47_0\boost\mpl\print.hpp|51 warning 4308| 負の整数定数が符号なしの型に変換されました。 main.cpp|94| コンパイルされたクラスの テンプレート のインスタンス化 'boost::mpl::print<T>' の参照を確認してください || with || [ || T=boost::mpl::vector40<boost::mpl::long_<1>,boost::mpl::integral_c<long,1>,boost::mpl::integral_c<long,2>,Fizz,Buzz,boost::mpl::integral_c<long,8>,boost::mpl::integral_c<long,13>,Fizz,boost::mpl::integral_c<long,34>,Buzz,boost::mpl::integral_c<long,89>,Fizz,boost::mpl::integral_c<long,233>,boost::mpl::integral_c<long,377>,Buzz,Fizz,boost::mpl::integral_c<long,1597>,boost::mpl::integral_c<long,2584>,boost::mpl::integral_c<long,4181>,FizzBuzz,boost::mpl::integral_c<long,10946>,boost::mpl::integral_c<long,17711>,boost::mpl::integral_c<long,28657>,Fizz,Buzz,boost::mpl::integral_c<long,121393>,boost::mpl::integral_c<long,196418>,Fizz,boost::mpl::integral_c<long,514229>,Buzz,boost::mpl::integral_c<long,1346269>,Fizz,boost::mpl::integral_c<long,3524578>,boost::mpl::integral_c<long,5702887>,Buzz,Fizz,boost::mpl::integral_c<long,24157817>,boost::mpl::integral_c<long,39088169>,boost::mpl::integral_c<long,63245986>,FizzBuzz> || ]
mpl::print を使用しているので、コンパイル時に結果も出力します。
msvc が多分一番見やすいと思う。
あと正しくメモ化されるために fibonacci には type を渡しています。
fibonacci<typename mpl::minus<N, mpl::long_<1> >::type>
mpl::minus