$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] Auto dispatch metaprogramming tricks
From: Terry Golubiewski (tjgolubi_at_[hidden])
Date: 2010-05-21 10:37:08
(see my comments below)
----- Original Message ----- 
From: "Steven Watanabe" <watanabesj_at_[hidden]>
Newsgroups: gmane.comp.lib.boost.user
To: <boost-users_at_[hidden]>
Sent: Friday, May 21, 2010 8:28 AM
Subject: Re: Auto dispatch metaprogramming tricks
> 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?
>>
>
> 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)
> > {};
>
> In Christ,
> Steven Watanabe
I think what Mr. Lamaison wants is:
give a message "handler" class like...
class Handler {
  void on(const M1&);
  void on(const M2&);
  void on(const M3&);
};
... is it possible to deduce ...
typedef mpl::vector<M1, M2, M3> HandledMessages;
... without knowing a priori the list of possible message messages
typedef mpl::vector<M1, M2, M3, ...> PosssibleMessages;
I think your example allows the user to determine if "Handler" has an "on" 
member function for a given a message type.
Though, to be honest, I'm not sure how your code works.  It looks 
fascinating!
Because, if you have to maintain PossibleMessages, then when a new message 
is added, the user would have to update PossibleMessages and and a method to 
"Handler", which is still two changes; i.e. no better.  Then again, 
filtering PossibleMessage using your "has_on" filter (using mpl::remove_if?) 
would be better if we assume that the list of PossibleMessages doesn't 
change very often, but users do regularly make Handlers that respond to 
various message subsets.
terry