Audacity 3.2.0
|
Class template generates single-dispatch, open method registry tables. More...
#include <AttachedVirtualFunction.h>
Classes | |
struct | Entry |
Member of registry of implementations of the method. More... | |
struct | Override |
For defining overrides of the method. More... | |
Public Types | |
using | Object = This |
This member name is declared in this class template and redeclared in each override. More... | |
using | Function = std::function< Return(Object &, Arguments...) > |
This member name is declared in this class template and redeclared in each override. More... | |
Public Member Functions | |
AttachedVirtualFunction () | |
At least one static instance must be created; more instances are harmless. More... | |
Static Public Member Functions | |
static Function | Implementation () |
A function returning a std::function, which you must define so that the program links. More... | |
static Return | Call (This &obj, Arguments ...arguments) |
Invoke the method – but only after static initialization time. More... | |
Private Types | |
using | Predicate = std::function< bool(This *) > |
using | Registry = std::vector< Entry > |
Static Private Member Functions | |
template<typename Subclass > | |
static void | Register (const Function &function) |
static Registry & | GetRegistry () |
Class template generates single-dispatch, open method registry tables.
Defines a "virtual" function with multiple bodies chosen by type-switch on the runtime class of the first argument, leaving the set of overrides open-ended for extension, but also requiring no modification of the definition of the base class of the type hierarchy that is switched on.
The invocation of the function is not as efficient as for true virtual functions but the advantage of this utility is greater compilation decoupling. Client code can attach its own virtual functions, non-intrusively, to the root of a class hierarchy defined in the core.
There is no collection of overriding function pointers into virtual function tables by the linker, but a registration of overrides into a table at static initialization time. This allows those implementations to be defined wherever is convenient, even in dynamically loaded libraries.
Beware that invocation of the function should not be done during initialization of file scope static objects. Dispatch might not go to the correct subclass case if initializations are not yet complete.
Example usage:
A core class:
Declare the attached function (in a header that Host.cpp need not include at all) as a specialization of the template:
Definitions needed:
Usage of the method somewhere else:
Derived classes from AbstractHost, not needing Client.h:
Overrides of the method, defined in any other .cpp file:
Tag | an incomplete type, to distinguish methods with otherwise identical parameters |
Return | the value returned by each override |
This | type of the first argument, a class with at least one true virtual function, the root of the hierarchy for the run-time type-switch |
Arguments | any number of types for the second and later arguments |
Definition at line 158 of file AttachedVirtualFunction.h.
using AttachedVirtualFunction< Tag, Return, This, Arguments >::Function = std::function< Return( Object&, Arguments... ) > |
This member name is declared in this class template and redeclared in each override.
Definition at line 165 of file AttachedVirtualFunction.h.
using AttachedVirtualFunction< Tag, Return, This, Arguments >::Object = This |
This member name is declared in this class template and redeclared in each override.
Definition at line 163 of file AttachedVirtualFunction.h.
|
private |
Definition at line 267 of file AttachedVirtualFunction.h.
|
private |
Definition at line 276 of file AttachedVirtualFunction.h.
AttachedVirtualFunction< Tag, Return, This, Arguments >::AttachedVirtualFunction | ( | ) |
At least one static instance must be created; more instances are harmless.
(There will be others if there are any overrides.)
|
inlinestatic |
Invoke the method – but only after static initialization time.
obj | Object on which to type-switch at run-time |
arguments | other arguments |
Definition at line 223 of file AttachedVirtualFunction.h.
References details::end(), entry, AttachedVirtualFunction< Tag, Return, This, Arguments >::GetRegistry(), and THROW_INCONSISTENCY_EXCEPTION.
Referenced by ChannelView::ChannelView(), TimeShiftHandle::Click(), anonymous_namespace{ClipMenus.cpp}::DoClipMove(), DoProjectTempoChange(), ClipMoveState::Init(), anonymous_namespace{SyncLock.cpp}::IsSeparatorTrack(), and anonymous_namespace{SyncLock.cpp}::IsSyncLockableNonSeparatorTrack().
|
staticprivate |
Referenced by AttachedVirtualFunction< Tag, Return, This, Arguments >::Call(), and AttachedVirtualFunction< Tag, Return, This, Arguments >::Register().
|
static |
A function returning a std::function, which you must define so that the program links.
It may return nullptr in case this must act somewhat as a "pure virtual", throwing InconsistencyException if the function is invoked on a subclass for which no override was defined
|
inlinestaticprivate |
Definition at line 258 of file AttachedVirtualFunction.h.
References AttachedVirtualFunction< Tag, Return, This, Arguments >::GetRegistry().