Boost logo

Boost :

Subject: Re: [boost] [functional] adding overload
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-01-17 05:46:22


On Tue, Jan 17, 2012 at 5:25 AM, Lorenzo Caminiti <lorcaminiti_at_[hidden]> wrote:
> On Mon, Jan 16, 2012 at 5:34 PM, Nathan Ridge <zeratul976_at_[hidden]> wrote:
>>
>>> This can be implemented using a suitable function_type that returns
>>> the function type result_type (arg1_type, ...) from a function type,
>>> function pointer, function reference, or from a functor which defines
>>> the types result_type, arg1_type, ... (as for example boost::function
>>> does).
>>
>> You can also implement it for any function object with a nontemplated
>> operator() even if it doesn't provide arg1_type etc. typedefs, by
>> examining the signature of its operator().
>
> Right! Below I'm wrapping function types, pointers, and references
> inside a functor type boost::function; if F is instead already a
> functor, I leave it unchanged (see functor_wrap). Then I manipulate
> the type of the functor operator() to generate the function type (see
> functor_unwrap). That allows me to pass any function type, pointer,
> reference, or any functor (which defines an operator()) to
> make_overload (without requiring the functor to typedef result_type,
> arg1_type, etc) :)
>
> One question: Can I do this even without the TYPEOFs inside deduce_type below?

Simplifying things a bit... but the typeof is still hanging in there :(

namespace boost { namespace functional {

namespace detail {

// Precondition: F is a functor.
template<typename F>
class functor_type {
    typedef BOOST_TYPEOF_TPL(&(F::operator())) call_ptr;
public:
    typedef
        typename boost::function_types::function_type<
            typename boost::mpl::push_front<
                  typename boost::mpl::pop_front< // Remove functor type (1st).
                    typename boost::function_types::parameter_types<
                            call_ptr>::type
>::type
                , typename boost::function_types::result_type<call_ptr>::type
>::type
>::type
    type;
};

// Precondition: F is a function type, pointer, reference, or functor.
template<typename F>
struct function_type {
    typedef
        typename boost::mpl::if_<boost::function_types::is_function<F>,
            boost::mpl::identity<F>
        ,
            typename boost::mpl::if_<boost::function_types::
                    is_function_pointer<F>,
                boost::remove_pointer<F>
            ,
                typename boost::mpl::if_<boost::function_types::
                        is_function_reference<F>,
                    boost::remove_reference<F>
                , // Requires, it's a functor.
                    functor_type<F>
>::type
>::type
>::type
    ::type type;
};

} // namespace detail

template<typename F0, typename F1, typename F2>
overload<
      typename detail::function_type<F0>::type
    , typename detail::function_type<F1>::type
    , typename detail::function_type<F2>::type
> make_overload(F0 f0, F1 f1, F2 f2) {
    return overload<
          typename detail::function_type<F0>::type
        , typename detail::function_type<F1>::type
        , typename detail::function_type<F2>::type
>(f0, f1, f2);
}

} } // namespace boost::functional

--Lorenzo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk