#include <boost/preprocessor.hpp> #include <boost/mpl/pair.hpp> #include <boost/mpl/same_as.hpp> #include <boost/mpl/always.hpp> #include <boost/mpl/switch.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/list.hpp> #define TYPE_DISPATCHER_MAX_ARITY 10 struct error_t; template<class T, class F> struct dispatch_case : public boost::mpl::pair<boost::mpl::same_as<T>, boost::mpl::always<F> > { }; template<class F> struct dispatch_default : public boost::mpl::pair< boost::mpl::always<boost::mpl::true_>, boost::mpl::always<F> > { }; template< class T, BOOST_PP_ENUM_BINARY_PARAMS(TYPE_DISPATCHER_MAX_ARITY, class Case, = dispatch_default<error_t> BOOST_PP_INTERCEPT) > struct dispatch : public boost::mpl::switch_< BOOST_PP_CAT(boost::mpl::list, TYPE_DISPATCHER_MAX_ARITY)< BOOST_PP_ENUM_PARAMS(TYPE_DISPATCHER_MAX_ARITY, Case) >, T > { }; ////////////////////////////// 以上ライブラリコード //////////////////////////// ///////////////////////////// 以下クライアントコード /////////////////////////// #include <iostream> struct char_func{ void operator()(){ std::cout << "char case" << std::endl; } }; struct short_func{ void operator()(){ std::cout << "short case" << std::endl; } }; struct int_func{ void operator()(){ std::cout << "int case" << std::endl; } }; struct default_func{ void operator()(){ std::cout << "default case" << std::endl; } }; template<class T> void type_dispatcher(T) { typename dispatch<T, dispatch_case<char, char_func>, dispatch_case<short, short_func>, dispatch_case<int, int_func>, dispatch_default< default_func> >::type()(); } int main() { type_dispatcher(char()); type_dispatcher(short()); type_dispatcher(int()); type_dispatcher(double()); }
ふと思いついたのを適当に書いただけ.
#あ,っていうか単にmpl::switch_のsyntax sugar書けば良いだけだった・・・orz.
#あ,これと自分が前作ったAS_FUNCTOR組み合わせたら普通の関数にもdispatch出来るじゃん.うひひ.
#MC++Dでやっているようなsymmetricなマルチディスパッチもすぐに書けそうだにゃー.MC++Dに書いてあること全部Boostで書き直したいけど時間がない〜,あぁもぅ!(じたばた)
#run-time bindにするにはどうすりゃええんかな?っていうかそもそもそういう要求が本当にあるかどうかすら,よく考えていないから分からん〜!(じたばた)