11#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
12# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
20#if ALIB_FEAT_SINGLETON_MAPPED
21# if !ALIB_MONOMEM || !ALIB_CONTAINERS
22# include <unordered_map>
39 export module ALib.Singletons;
41# if ALIB_FEAT_SINGLETON_MAPPED
42# if ALIB_DEBUG && ALIB_STRINGS
48 import ALib.Containers.HashTable;
54# if ALIB_FEAT_SINGLETON_MAPPED
68#if ALIB_FEAT_SINGLETON_MAPPED && !DOXYGEN
69namespace alib::singletons::hidden {
70# if ALIB_MONOMEM && ALIB_CONTAINERS
72 lang::TypeFunctors::Hash,
73 lang::TypeFunctors::EqualTo,
75 Recycling::None > singletonMap;
77 extern std::unordered_map< lang::TypeFunctors::Key,
void *,
78 lang::TypeFunctors::Hash,
79 lang::TypeFunctors::EqualTo > singletonMap;
81# if !ALIB_MONOMEM && !ALIB_SINGLE_THREADED
82 extern std::mutex singletonMapMutex;
84 extern ALIB_DLL void *getSingleton(
const std::type_info &type);
85 extern ALIB_DLL void storeSingleton(
const std::type_info &type,
void *theSingleton);
86 extern ALIB_DLL void removeSingleton(
const std::type_info &type);
103template<
typename TDerivedClass>
110 #if !ALIB_FEAT_SINGLETON_MAPPED
112 static TDerivedClass singleton;
115 #if ALIB_SINGLE_THREADED
116 using TSingletonStorage = TDerivedClass *;
118 using TSingletonStorage = std::atomic<TDerivedClass *>;
122 static TSingletonStorage singleton =
nullptr;
125 TDerivedClass *result = singleton;
126 if (result !=
nullptr)
133 #if !ALIB_SINGLE_THREADED
137 std::lock_guard<std::mutex> guard(hidden::singletonMapMutex);
142 void *storedSingleton = hidden::getSingleton(
typeid(TDerivedClass));
143 if (storedSingleton !=
nullptr) {
144 singleton =
dynamic_cast<TDerivedClass *
>(
150 auto *firstInstance =
new TDerivedClass();
151 hidden::storeSingleton(
typeid(TDerivedClass),
157 return *firstInstance;
159 return *(singleton = firstInstance);
169 #if ALIB_FEAT_SINGLETON_MAPPED
170 #if !ALIB_SINGLE_THREADED
174 std::lock_guard<std::mutex> guard(hidden::singletonMapMutex);
177 hidden::removeSingleton(
typeid(TDerivedClass));
207#if ALIB_FEAT_SINGLETON_MAPPED && ALIB_DEBUG
211#if ALIB_MONOMEM && ALIB_CONTAINERS
233 lang::TypeFunctors::Hash,
234 lang::TypeFunctors::EqualTo,
239 lang::TypeFunctors::Hash,
static TDerivedClass & GetSingleton()
virtual ~Singleton()
Virtual destructor.
#define ALIB_LOCK_RECURSIVE_WITH(lock)
HashTable< TAllocator, TPairDescriptor< TKey, TMapped >, THash, TEqual, THashCaching, TRecycling > HashMap
ALIB_DLL RecursiveLock GLOBAL_ALLOCATOR_LOCK
HashMap< MonoAllocator, lang::TypeFunctors::Key, void *, lang::TypeFunctors::Hash, lang::TypeFunctors::EqualTo, lang::Caching::Auto, Recycling::None > & DbgGetSingletons()
singletons::Singleton< T > Singleton
Type alias in namespace alib.
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
containers::HashMap< TAllocator, TKey, TMapped, THash, TEqual, THashCaching, TRecycling > HashMap
Type alias in namespace alib.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
const ::std::type_info * Key
The key type.