12#ifndef __AUDACITY_ATTACHED_VIRTUAL_FUNCTION__
13#define __AUDACITY_ATTACHED_VIRTUAL_FUNCTION__
157template<
typename Tag,
typename Return,
typename This,
typename... Arguments >
192 std::is_base_of_v< typename Overridden::Object, Object >,
193 "overridden class must be a base of the overriding class"
200 typename Overridden::Object &
object, Arguments &&...arguments )
202 return Overridden::Implementation()(
203 object, std::forward< Arguments >( arguments )... );
209 static std::once_flag
flag;
210 std::call_once(
flag, []{
213 Register< Subclass >( [=]( This &obj, Arguments ...arguments ){
214 return implementation(
215 static_cast< Subclass&
>( obj ),
216 std::forward< Arguments >( arguments )... );
225 Arguments ...arguments
238 auto iter = registry.rbegin(),
end = registry.rend();
239 for ( ; iter !=
end; ++iter ) {
241 if (
entry.predicate( &obj ) )
243 return entry.function(
244 obj, std::forward< Arguments >( arguments )... );
247 throw std::bad_function_call{};
249 catch (
const std::bad_function_call& ) {
257 template<
typename Sub
class >
262 []( This *b ){
return dynamic_cast< Subclass *
>( b ) !=
nullptr; },
281#define DECLARE_EXPORTED_ATTACHED_VIRTUAL(DECLSPEC, Name) \
282 template<> DECLSPEC Name::AttachedVirtualFunction(); \
283 template<> auto DECLSPEC Name::GetRegistry() -> Registry &; \
284 template<> auto DECLSPEC Name::Implementation() -> Function
287#define DEFINE_ATTACHED_VIRTUAL(Name) \
288 template<> Name::AttachedVirtualFunction() \
290 static std::once_flag flag; \
291 std::call_once( flag, []{ Register<Object>( Implementation() ); } ); \
293 template<> auto Name::GetRegistry() -> Registry & \
295 static Registry registry; \
298 static Name register ## Name ; \
299 template<> auto Name::Implementation() -> Function
302#define DEFINE_ATTACHED_VIRTUAL_OVERRIDE(Name) \
303 static Name register ## Name ; \
304 template<> template<> auto Name::Implementation() -> Function \
static ProjectFileIORegistry::AttributeWriterEntry entry
MessageBoxException for violation of preconditions or assertions.
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
Class template generates single-dispatch, open method registry tables.
static Registry & GetRegistry()
static Return Call(This &obj, Arguments ...arguments)
Invoke the method – but only after static initialization time.
static void Register(const Function &function)
static Function Implementation()
A function returning a std::function, which you must define so that the program links.
AttachedVirtualFunction()
At least one static instance must be created; more instances are harmless.
This Object
This member name is declared in this class template and redeclared in each override.
std::function< Return(Object &, Arguments...) > Function
This member name is declared in this class template and redeclared in each override.
std::function< bool(This *) > Predicate
const char * end(const char *str) noexcept
Member of registry of implementations of the method.
For defining overrides of the method.
static Function Implementation()
A function returning a std::function that must be defined so that the program links.
static Return Callthrough(typename Overridden::Object &object, Arguments &&...arguments)
May be used in the body of the overriding function, defining it in terms of the overridden one.
Override()
At least one static instance must be created; more instances are harmless.