Bromeon
Public Member Functions
thor::SingleDispatcher< B, R > Class Template Reference

Class that is able to perform dynamic dispatch on multiple functions with one parameter. More...

Inheritance diagram for thor::SingleDispatcher< B, R >:
Inheritance graph

List of all members.

Public Member Functions

 SingleDispatcher (bool supportDerivedToBase=false)
 Default constructor.
template<class D >
void Register (R(*globalFunction)(D#))
 Registers a global function.
template<class D , class C >
void Register (R(C::*memberFunction)(D#), C &object)
 Registers a member function.
template<class D , typename Fn >
void Register (const Fn &functionObject)
 Registers a function object.
Call (B arg) const
 Dispatches the dynamic type of arg and invokes the corresponding function.

Detailed Description

template<class B, typename R = void>
class thor::SingleDispatcher< B, R >

Class that is able to perform dynamic dispatch on multiple functions with one parameter.

Sometimes you encounter the situation where you need to implement polymorphic behavior, but you cannot or don't want to add a virtual function to an existing class hierarchy. Here comes dynamic dispatch into play: You define free functions, which can be treated by the dispatcher like virtual functions.

Template Parameters:
BReference or pointer to polymorphic class, which is the base class of every dispatched function's parameter type. When B is a pointer, the arguments of the dispatched functions shall be pointers too (the same applies to references). If B is a pointer or reference to const, the dispatched functions cannot modify their arguments. In this case, the dispatched functions shall have arguments of type pointer or reference to const, too.
RReturn type of the dispatched functions.
 // Example class hierarchy
 class Base { public: virtual ~Base() {} };
 class Derived1 : public Base {};
 class Derived2 : public Base {};

 // Free functions for the derived types
 void Func(Derived1* d);
 void Func(Derived2* d);

 // Create dispatcher and register functions
 thor::SingleDispatcher<Base*> dispatcher;
 dispatcher.Register<Derived1>(&Func);
 dispatcher.Register<Derived2>(&Func);

 // Invoke functions on base class pointer
 Base* ptr = new Derived1;
 dispatcher.Call(ptr); // Invokes void Func(Derived1* d);
 delete ptr;

Constructor & Destructor Documentation

template<class B, typename R = void>
thor::SingleDispatcher< B, R >::SingleDispatcher ( bool  supportDerivedToBase = false) [explicit]

Default constructor.

Parameters:
supportDerivedToBaseSpecifies whether derived-to-base conversions are supported. If no function for a derived class is found, the dispatcher will look for functions taking base class parameters and upcast the arguments, if possible. You need to register the class hierarchy using the macros in Rtti.hpp. On average, calls with derived-to-base conversions are as fast as direct matches, but this feature requires a small memory overhead.

Member Function Documentation

template<class B, typename R = void>
R thor::SingleDispatcher< B, R >::Call ( arg) const

Dispatches the dynamic type of arg and invokes the corresponding function.

Note that the argument's dynamic type must match exactly with the registered type, unless you enabled derived-to-base conversions in the constructor and specified the class hierarchy. In the latter case, the function with the best match is chosen for overload resolution.

Parameters:
argFunction argument as a reference or pointer to the base class.
Returns:
The return value of the dispatched function, if any.
Exceptions:
FunctionCallExceptionwhen no corresponding function is found.
template<class B, typename R = void>
template<class D >
void thor::SingleDispatcher< B, R >::Register ( R(*)(D#)  globalFunction)

Registers a global function.

Template Parameters:
DType of the derived class. Must be explicitly specified.
Parameters:
globalFunctionPointer to function to register.

Note that # is a placeholder for either & or *. The type D# has the same attributes as B (pointer, reference, const-qualification): For instance, B=const Base& implies D#=const Derived1&.
Example (class hierarchy and dispatcher declaration missing):

 // Overloaded global or namespace-level functions
 void Func(Derived1&);
 void Func(Derived2&);

 // Register functions
 dispatcher.Register<Derived1>(&Func);
 dispatcher.Register<Derived2>(&Func);
Precondition:
A function taking an argument of dynamic type D is not registered yet.
template<class B, typename R = void>
template<class D , class C >
void thor::SingleDispatcher< B, R >::Register ( R(C::*)(D#)  memberFunction,
C &  object 
)

Registers a member function.

Template Parameters:
DType of the derived class. Must be explicitly specified.
CClass that holds the member function.
Parameters:
memberFunctionPointer to member function to register.
objectReference to the object on which the member function is invoked.

Note that # is a placeholder for either & or *. The type D# has the same attributes as B (pointer, reference, const-qualification): For instance, B=const Base& implies D#=const Derived1&.
Example (class hierarchy and dispatcher declaration missing):

 // Class with member functions
 struct MyClass
 {
     void MemFunc(Derived1&);
     void MemFunc(Derived2&);
 } obj;

 // Register overloaded functions
 dispatcher.Register<Derived1>(&MyClass::MemFunc, obj);
 dispatcher.Register<Derived2>(&MyClass::MemFunc, obj);
Precondition:
A function taking an argument of dynamic type D is not registered yet.
template<class B, typename R = void>
template<class D , typename Fn >
void thor::SingleDispatcher< B, R >::Register ( const Fn &  functionObject)

Registers a function object.

Template Parameters:
DType of the derived class. Must be explicitly specified.
FnType of the function object. Can be deduced from the argument.
Parameters:
functionObjectFunctor to register.

Incomplete example using a function object (you can also have separate functors for each function):

 // Class for function objects
 struct Functor
 {
    void operator() (Derived1&);
    void operator() (Derived2&);
 };

 // Register functor
 dispatcher.Register<Derived1>(Functor());
 dispatcher.Register<Derived2>(Functor());
Precondition:
A function taking an argument of dynamic type D is not registered yet.

The documentation for this class was generated from the following file: