|
Boost Users : |
Subject: Re: [Boost-users] Auto dispatch metaprogramming tricks
From: Kim Kuen Tang (kuentang_at_[hidden])
Date: 2010-05-21 10:13:08
Steven Watanabe schrieb:
> AMDG
>
> Alexander Lamaison wrote:
>> I would like to dispatch messages to a class based simply on the
>> *presence*
>> of a message handler method.
>>
>> Currently, the classes maintain an MPL vector of the messages they
>> handle
>> and must implement a on(message<MESSAGE_ID>) method for each one. The
>> dispatcher uses this compile-time list to build the dispatching
>> code. This
>> means the information is maintained twice and may fall out of sync (e.g.
>> adding the handler but forgetting to update the message vector.
>>
>> Are there any template metaprogramming tricks I can employ to
>> dispatch the
>> message to a handler method if it exists and the default handler
>> otherwise?
>> All this information is available at compile time. The question is are
>> templates are powerful enough to make use of it?
>>
Hi Alexander,
here is a class that i use to check the existence of a member function.
It works on MSVC 9. But as indicated by strasser ( sorry, cant find your
name in the email)
it might be not portable.
template<typename T>
struct HasSizeMethod
{
private:
template<typename U, typename U::size_type
(U::*)() const>
struct SFINAE {};
typedef char yes_type;
typedef char(&no_type)[2];
template<typename U>
static no_type test_HasSizeMethod(...);
template<typename U>
static yes_type
test_HasSizeMethod(SFINAE<U,&U::size>*);
public:
typedef bool value_type;
BOOST_STATIC_CONSTANT(value_type
, value = sizeof(yes_type) ==
sizeof(test_HasSizeMethod<T>(0) ) );
typedef mpl::bool_<value> type;
};
> Yes. The code looks something like this:
>
> typedef char no;
> struct yes { char dummy[2]; };
>
> struct has_on_result {
> has_on_result operator,(int);
> };
>
> no check_on_result(const has_on_result&);
> yes check_on_result(...);
>
> template<class T>
> struct has_on_impl : T {
> using T::on;
> has_on_result on(...);
> };
>
> template<class T, class M>
> struct has_on : boost::mpl::bool_<
> sizeof(check_on_result(((has_on_impl<T>*)0)->on(*((M*)0)) , 0)) !=
> sizeof(no)
> > {};
>
Hi Steve,
as indicated by strasser i have also difficulties to compile your code.
But your code seems to be more generic, since you dont need to provide
the result_type of the member function.
Can you provide a working example?
# include <boost/cstdlib.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/assert.hpp>
typedef char no;
struct yes { char dummy[2]; };
struct has_on_result {
has_on_result operator,(int);
};
no check_on_result(const has_on_result&);
yes check_on_result(...);
template<class T>
struct has_on_impl : T {
using T::on;
has_on_result on(...);
};
template<class T, class M>
struct has_on : boost::mpl::bool_<
sizeof(check_on_result(((has_on_impl<T>*)0)->on(*((M*)0)) , 0)) !=
sizeof(no)
> {};
struct has_on_struct
{
int on(int ) const
{
return 1;
}
};
struct arbitrary_struct
{
int no(int) const
{
return 1;
}
};
int main()
{
BOOST_MPL_ASSERT((has_on<has_on_struct,int> ));
return boost::exit_success;
}
There is also a more generic working example in the ticket. See
https://svn.boost.org/trac/boost/ticket/3783
> In Christ,
> Steven Watanabe
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net