12#ifndef __AUDACITY_CLIENT_DATA__
13#define __AUDACITY_CLIENT_DATA__
34template<
typename Object >
using UniquePtr = std::unique_ptr< Object >;
37template<
typename Object >
using BarePtr = Object*;
46 template<
typename>
class Owner =
UniquePtr
214 template<
typename>
class Pointer =
UniquePtr,
224 static_assert( std::has_virtual_destructor<ClientData>::value,
225 "ClientData::Site requires a data class with a virtual destructor" );
236 auto size = factories.mObject.size();
248 {
mData = std::move(other.mData);
return *
this; }
273 mIndex = factories.mObject.size();
274 factories.mObject.emplace_back( std::move(
factory ) );
280 other.mOwner =
false;
287 if (
mIndex < factories.mObject.size() )
288 factories.mObject[
mIndex] =
nullptr;
308 template<
typename Sub
class = ClientData >
312 return DoGet< Subclass >( data,
key );
317 template<
typename Sub
class = const ClientData >
319 std::enable_if_t< std::is_const< Subclass >::value, Subclass & >
322 return DoGet< Subclass >( data,
key );
332 template<
typename Sub
class = ClientData >
336 return DoFind< Subclass >( data,
key );
341 template<
typename Sub
class = const ClientData >
343 std::enable_if_t< std::is_const< Subclass >::value, Subclass * >
346 return DoFind< Subclass >( data,
key );
354 template<
typename ReplacementPo
inter >
357 ReplacementPointer &&replacement
365 *iter = std::forward< ReplacementPointer >( replacement );
379 template<
typename Function >
383 for(
auto &pObject : data.mObject ) {
392 template<
typename Function >
393 void ForEach(
const Function &function )
const
396 for(
auto &pObject : data.mObject ) {
399 const auto &c_ref = *ptr;
411 template<
typename Function >
415 for(
auto &pObject : data.mObject ) {
417 if ( ptr && function ( *ptr ) )
425 template<
typename Function >
429 for(
auto &pObject : data.mObject ) {
432 const auto &c_ref = *ptr;
433 if ( function( c_ref ) )
450 size = factories.mObject.size();
457 for (
size_t ii = 0; ii <
size; ++ii, ++iter )
458 static_cast< void >(
Build( data, iter, ii ) );
478 auto &pointer = create ?
Build( data, iter, index ) : *iter;
482 template<
typename Sub
class >
485 const auto &d =
Slot( data,
key,
true );
490 return static_cast< Subclass&
>( *d );
493 template<
typename Sub
class >
496 const auto &d =
Slot( data,
key,
false );
500 return static_cast< Subclass*
>( &*d );
526 if (data.
mObject.size() <= index)
527 data.
mObject.resize(index + 1);
530 static typename DataContainer::iterator
inline
538 auto result = data.
mObject.begin();
539 std::advance( result, index );
544 typename DataContainer::iterator iter,
size_t index )
549 auto &result = *iter;
553 auto &
factory = factories.mObject[index];
Some implementation details for ClientData.
static const AudacityProject::AttachedObjects::RegisteredFactory key
MessageBoxException for violation of preconditions or assertions.
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
RegisteredFactory(RegisteredFactory &&other)
RegisteredFactory(DataFactory factory)
Utility to register hooks into a host class that attach client data.
size_t size() const
How many attachment pointers are in the Site.
Site & operator=(const Site &other)
ClientData * FindIf(const Function &function)
Return pointer to first attachment in this that is not null and satisfies a predicate,...
Pointer< ClientData > DataPointer
static Locked< DataFactories > GetFactories()
Locked< DataContainer > GetData()
DataContainer mData
Container of pointers returned by factories, per instance of Host class.
static size_t slots()
How many static factories have been registered with this specialization of Site.
Subclass * DoFind(Locked< DataContainer > &data, const RegisteredFactory &key)
static DataContainer::iterator GetIterator(Locked< DataContainer > &data, size_t index)
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
static void EnsureIndex(Locked< DataContainer > &data, size_t index)
Locked< const DataContainer > GetData() const
void ForEach(const Function &function)
Invoke function on each ClientData object that has been created in this.
void ForEach(const Function &function) const
Invoke function on each ClientData object that has been created in this.
DataPointer & Build(Locked< DataContainer > &, typename DataContainer::iterator iter, size_t index)
void BuildAll()
For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it.
Subclass & DoGet(Locked< DataContainer > &data, const RegisteredFactory &key)
std::function< DataPointer(Host &) > DataFactory
Type of function from which RegisteredFactory is constructed; it builds attachments.
auto Find(const RegisteredFactory &key) const -> std::enable_if_t< std::is_const< Subclass >::value, Subclass * >
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
const ClientData * FindIf(const Function &function) const
Return pointer to first attachment in this that is not null and satisfies a predicate,...
auto Get(const RegisteredFactory &key) const -> std::enable_if_t< std::is_const< Subclass >::value, Subclass & >
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
void Assign(const RegisteredFactory &key, ReplacementPointer &&replacement)
Reassign Site's pointer to ClientData.
decltype(Dereferenceable(std::declval< DataPointer & >())) Slot(Locked< DataContainer > &data, const RegisteredFactory &key, bool create)
Utility ClientData::Site to register hooks into a host class that attach client data.
static const Ptr & Dereferenceable(Ptr &p)
Conversion allowing operator * on any Pointer parameter of ClientData::Site.
Object * BarePtr
This template-template parameter for ClientData::Site risks dangling pointers, so be careful.
CopyingPolicy
Statically specify how the ClientData::Site implements its copy constructor and assignment.
@ SkipCopying
ignore the source and leave empty
LockingPolicy
Statically specify whether there is mutual exclusion (separately for the table of factories,...
std::unique_ptr< Object > UniquePtr
A one-argument alias template for the default template-template parameter of ClientData::Site.
static RegisteredToolbarFactory factory
A convenient default parameter for class template Site.
A convenient base class defining abstract virtual Clone() for a given kind of pointer.
virtual PointerType Clone() const =0
Owner< Base > PointerType
Decorator template injects copy and move operators for container of pointers.
Decorator template injects type Lock and method lock() into interface of Object.
Decorated reference to a ClientData::Lockable, with a current lock on it.