#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にするにはどうすりゃええんかな?っていうかそもそもそういう要求が本当にあるかどうかすら,よく考えていないから分からん〜!(じたばた)