$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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://listarchives.boost.org/mailman/listinfo.cgi/boost-users
>