50 using Identifier =
const char*;
58 [[
nodiscard]]
inline int getCounter()
const
70 inline void increaseCounter()
76 virtual ~FuncWrapperBase();
79 template<
typename T,
typename ...
Args>
80 class FuncWrapper
final
81 :
public FuncWrapperBase
84 const std::function<
T(
Args ...)> mFunc;
87 explicit FuncWrapper(std::function<
T(
Args ...)>
pFunc)
96 return mFunc(
pArgs ...);
103 QList<Wrapper> mInstancesCreator;
109 QList<std::function<
void* (
bool)>> mSingletonCreator;
114 static Env& getInstance();
119 Q_ASSERT(!mSingletonHandler.isNull());
121 if (!QCoreApplication::startingUp() && !QCoreApplication::applicationName().
startsWith(
QLatin1String(
"Test_")))
127 qDebug() <<
"Create singleton:" << T::staticMetaObject.className();
130 if constexpr (std::is_abstract_v<T> && std::is_destructible_v<T>)
139 QObject::connect(ptr, &QObject::destroyed, ptr, [] {
140 qDebug() <<
"Destroy singleton:" << T::staticMetaObject.className();
142 mSingletonHandler->add(ptr);
143 mSingletonCreator << std::bind(&Env::getOrCreateSingleton<T>,
this, std::placeholders::_1);
150 T* getOrCreateSingleton(
bool pCreate =
false)
166 inline T* fetchRealSingleton()
168 if constexpr (QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value)
174 if constexpr (std::is_abstract_v<T> && std::is_destructible_v<T>)
176 static_assert(std::has_virtual_destructor_v<T>,
"Destructor must be virtual");
181 return &T::getInstance();
188 inline std::enable_if_t<QtPrivate::IsGadgetHelper<T>::IsRealGadget,
T*> checkObjectInfo(Identifier
pId,
T*
pObject)
const
196 inline std::enable_if_t<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
T*> checkObjectInfo(Identifier
pId,
T*
pObject)
const
198 if (!std::is_base_of<ThreadSafe, T>() &&
pObject->thread() != QThread::currentThread())
200 qWarning() <<
pId <<
"was created in" <<
pObject->thread()->objectName() <<
"but is requested by" << QThread::currentThread()->objectName();
211 inline T* fetchSingleton()
213 static_assert(QtPrivate::IsGadgetHelper<T>::IsRealGadget || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
214 "Singletons needs to be a Q_GADGET or an QObject/Q_OBJECT");
216 const Identifier
id = T::staticMetaObject.className();
220 obj = mInstancesSingleton.value(
id);
225 return checkObjectInfo(
id,
static_cast<T*
>(
obj));
229 template<
typename T,
typename ...
Args>
232 if constexpr (std::is_constructible_v<std::remove_pointer_t<T>,
Args ...>)
234 if constexpr (std::is_pointer_v<T>)
236 using t = std::remove_pointer_t<T>;
237 return new t(std::forward<Args>(
pArgs) ...);
241 return T(std::forward<Args>(
pArgs) ...);
246 static_assert(std::is_pointer_v<T>,
"It is impossible to return implementation of interface by value. Use pointer or add constructor!");
254 template<
typename T,
typename ...
Args>
281 Q_ASSERT(mSingletonHandler.isNull());
283 QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, mSingletonHandler.data(), &QObject::deleteLater);
285 const auto copy = mSingletonCreator;
286 mSingletonCreator.clear();
287 for (
const auto&
func : copy)
300 getInstance().initialize();
307 return getInstance().fetchSingleton<
T>();
311 template<
typename T,
typename ...
Args>
314 return getInstance().createObject<
T>(std::forward<Args>(
pArgs) ...);
321 static_assert(QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
"Shared class needs to be an QObject/Q_OBJECT");
323 const Identifier
className = T::staticMetaObject.className();
325 auto&
holder = getInstance();
326 holder.mSharedInstancesLock.lockForRead();
328 holder.mSharedInstancesLock.unlock();
337 shared = QSharedPointer<T>::create();
351 template<
typename T,
typename ...
Args>
354 auto&
holder = getInstance();
357 for (
const auto&
mock : std::as_const(
holder.mInstancesCreator))
359 if (
mock.dynamicCast<FuncWrapper<T, Args ...>>())
361 return mock->getCounter();
369 template<
typename T,
typename ...
Args>
376 auto&
holder = getInstance();
380 while (
iter.hasNext())
383 if (
iter.value().dynamicCast<FuncWrapper<T, Args ...>>())
QSharedPointer< T > decodeObject(const QByteArray &pData, bool pLogging=true)
Template function for decoding an OpenSSL type from DER encoded QByteArray.
Definition ASN1TemplateUtil.h:114