Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement partial dispatch #239

Merged
merged 3 commits into from
Jan 7, 2021

Conversation

davidbrochart
Copy link
Member

Checklist

  • The title and the commit message(s) are descriptive
  • Small commits made to fix your PR have been squashed to avoid history pollution
  • Tests have been added for new features or bug fixes
  • API of new functions and classes are documented

Description

@davidbrochart
Copy link
Member Author

The first commit implemented a partial dispatch which supported only 1 argument on which to dispatch and 1 argument on which not to dispatch ("ignored argument").
This second commit supports an arbitrary number of arguments on which to dispatch and 1 ignored argument.

@davidbrochart
Copy link
Member Author

I'm wondering if it's possible to have the partial dispatcher not separate from the normal dispatcher, with an optional ignored argument.

@JohanMabille
Copy link
Member

JohanMabille commented Jan 6, 2021

It's actually possible and I think it's the way to go.Let's illustrate this with the basic_fast_dispatcher, the reasoning is similar with the basic_dispatcher. The idea is to add a template parameter for the non dispatched arguments after the return_type parameter:

template
    <
        class type_list,
        class return_type,
        class undispatched_type_list
        class callback_type
    >
    class basic_fast_dispatcher;

and define the specialization for mpl::vector only:

    template
    <
        class return_type,
        class callback_type,
        class... B,
        class... T,
    >
    class basic_fast_dispatcher<mpl::vector<B...>, return_type, mpl::vector<T...>, callback_type>
    {
        // Implementation very similar to the existing one except that you forward the non dispatched arguments
        inline return_type dispatch(B&... args, T&... udargs) const
        {
            index_type index = {{args.get_class_index()...}};
            return dispatch_impl<0>(m_callbacks, index, args..., udargs...);
        }
    };

The template parameter for non dispatched type is also added to the functor_dispatcher, and is defaulted to the empty mpl::vector:

    template
    <
        class type_list,
        class return_type,
        class undispatched_type = mpl::vector<>,
        template <class, class> class casting_policy = dynamic_caster,
        template <class, class, class> class dispatcher = basic_dispatcher
    >
    class functor_dispatcher;

        template
    <
        class return_type, 
        template <class, class> class casting_policy,
        template <class, class, class> class dispatcher,
        class... B,
        class... T
    >
    class functor_dispatcher<mpl::vector<B...>, return_type, mpl::vector<T...>, casting_policy, dispatcher>
    {
    // Similar implementation except that you forward the additional arguments without casting them:
        template <class... D, class Fun>
        void insert(const Fun& fun)
        {
            functor_type f([fun](B&... args, T&... targs) -> return_type
            {
                return fun(casting_policy<D&, B&>::cast(args)..., targs...);
            });
            m_backend.template insert<D...>(std::move(f));
        }

        inline return_type dispatch(B&... args, T&... targs) const
        {
            return m_backend.dispatch(args..., targs);
        }
    };

@davidbrochart
Copy link
Member Author

Thanks @JohanMabille.
It's still annoying to have to set a default parameter (for which you want the default value) when you want to set a parameter that is further in the list. Maybe @serge-sans-paille could use his C++ fu to do something similar to params14 for template parameters 😄

@JohanMabille
Copy link
Member

Awesome!

@JohanMabille JohanMabille merged commit 8680459 into xtensor-stack:master Jan 7, 2021
@davidbrochart davidbrochart deleted the partial_dispatch branch January 7, 2021 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants