I l@ve RuBoard Previous Section Next Section

11.11 BasicDispatcher and BasicFastDispatcher as Policies

BasicFastDispatcher (matrix based) is preferable to BasicDispatcher (map based) when speed is a concern. However, the nice advanced classes FnDispatcher and FunctorDispatcher are built around BasicDispatcher. Should we develop two new classes—FnFastDispatcher and FunctorFastDispatcher—that use BasicFastDispatcher as their back end?

A better idea is to try to adapt FnDispatcher and FunctorDispatcher to use either BasicDispatcher or BasicFastDispatcher, depending on a template parameter. That is, make the dispatcher a policy for the classes FnDispatcher and FunctorDispatcher, much as we did with the casting strategy.

The task of morphing the dispatcher into a policy is eased by the fact that Basic Dispatcher and BasicFastDispatcher have the same call interface. This makes replacing one with the other as easy as changing a template argument.

The following is the revised declaration of FnDispatcher (FunctorDispatcher's declaration is similar). The changes are shown in bold.



template


<


   class BaseLhs,


   class BaseRhs = BaseLhs,


   typename ResultType = void,


   template <class, class>


      class CastingPolicy = DynamicCaster,


   template <class, class, class, class>


      class DispatcherBackend = BasicDispatcher


>


class FnDispatcher; // similarly for FunctorDispatcher


Table 11.1. DispatcherBackend Policy Requirements
Expression Return Type Notes
copy, assign, swap, destroy   Value semantics.
backEnd.Add<SomeLhs, SomeRhs>(callback) void Add a callback to the backEnd object for types SomeLhs and SomeRhs.
backEnd.Go(BaseLhs&, BaseRhs&) ResultType Performs a lookup and a dispatch for the two objects. Throws std::runtime_error if a handler is not found.
backEnd.Remove<SomeLhs, SomeRhs>() bool Removes the callback for the types SomeLhs and SomeRhs. Returns true if there was a callback.
backEnd.HandlerExists<SomeLhs, SomeRhs>() bool Returns true if a callback is registered for the types SomeLhs and SomeRhs. No callback is added.

The two classes themselves undergo very few changes.

Let's clarify the DispatcherBackend policy requirements. First of all, obviously, DispatcherBackend must be a template with four parameters. The parameter semantics are, in order

  • Left-hand operand type

  • Right-hand operand type

  • Return type of the callback

  • The callback type

In Table 11.1, BackendType represents an instantiation of the dispatcher back-end template, and backEnd represents a variable of that type. The table contains functions that we haven't mentioned yet—don't worry. A complete dispatcher must come with functions that remove callbacks and that do a "passive" lookup without calling the callback. These are trivial to implement; you can see them in Loki's source code, file MultiMethods.h.

    I l@ve RuBoard Previous Section Next Section