12 #include <QMetaObject>
15 #include <QSharedPointer>
16 #include <QWeakPointer>
19 #include <QMutableVectorIterator>
28 template<
typename T>
T*
singleton(
bool& pTakeOwnership);
34 friend class ::test_Env;
56 virtual ~FuncWrapperBase();
59 template<
typename T,
typename ... Args>
60 class FuncWrapper final
61 :
public FuncWrapperBase
64 const std::function<
T(Args ...)> mFunc;
67 FuncWrapper(
const std::function<
T(Args ...)>& pFunc)
73 virtual ~FuncWrapper()
78 T operator()(Args&& ... pArgs)
81 return mFunc(std::forward<Args>(pArgs) ...);
87 using Wrapper = std::shared_ptr<FuncWrapperBase>;
88 QVector<Wrapper> mInstancesCreator;
99 using Identifier =
const char*;
100 QMap<Identifier, Type> mTypeInfo;
101 QMap<Identifier, void*> mInstancesUnmanaged;
102 QMap<Identifier, std::shared_ptr<void> > mInstancesOwnership;
103 QMap<Identifier, QWeakPointer<QObject> > mSharedInstances;
105 static Env& getInstance();
107 void storeSingleton(Identifier pId,
void* pObject);
108 void storeSingleton(Identifier pId, std::shared_ptr<void> pObject);
109 void removeStoredSingleton(Identifier pId);
110 void* fetchStoredSingleton(Identifier pId)
const;
113 typename std::enable_if<std::is_abstract<T>::value && std::is_destructible<T>::value,
T*>::type storeSingleton(Identifier pId)
115 static_assert(std::has_virtual_destructor<T>::value,
"Destructor must be virtual");
117 bool ownership =
true;
118 T* obj = singleton<T>(ownership);
122 storeSingleton(pId, std::shared_ptr<void>(obj));
126 storeSingleton(pId, obj);
133 typename std::enable_if<!std::is_destructible<T>::value,
T*>::type storeSingleton(Identifier pId)
135 T* obj = &T::getInstance();
136 storeSingleton(pId, obj);
142 typename std::enable_if<std::is_default_constructible<T>::value,
T*>::type storeSingleton(Identifier pId)
144 auto obj = std::make_shared<T>();
145 storeSingleton(pId, obj);
151 inline T* fetchSingleton()
153 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
154 static_assert(QtPrivate::IsGadgetHelper<T>::IsRealGadget || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
155 "Singletons needs to be a Q_GADGET or an QObject/Q_OBJECT");
157 static_assert(QtPrivate::IsGadgetHelper<T>::Value || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
158 "Singletons needs to be a Q_GADGET or an QObject/Q_OBJECT");
161 Identifier
id = T::staticMetaObject.className();
162 void* obj = fetchStoredSingleton(
id);
166 obj = storeSingleton<T>(id);
169 return static_cast<T*
>(obj);
173 template<
typename T,
typename ... Args>
174 inline typename std::enable_if<!std::is_constructible<typename std::remove_pointer<T>::type, Args ...>::value,
T>::type newObject(Args&& ... pArgs)
const
176 static_assert(std::is_pointer<T>::value,
"It is impossible to return implementation of interface by value. Use pointer or add constructor!");
177 auto obj = createNewObject<T>(std::forward<Args>(pArgs) ...);
183 template<
typename T,
typename ... Args>
184 inline typename std::enable_if<std::is_pointer<T>::value,
T>::type internalNewObject(Args&& ... pArgs)
const
186 using t =
typename std::remove_pointer<T>::type;
187 return new t(std::forward<Args>(pArgs) ...);
191 template<
typename T,
typename ... Args>
192 inline typename std::enable_if<!std::is_pointer<T>::value,
T>::type internalNewObject(Args&& ... pArgs)
const
194 return T(std::forward<Args>(pArgs) ...);
198 template<
typename T,
typename ... Args>
199 inline typename std::enable_if<std::is_constructible<typename std::remove_pointer<T>::type, Args ...>::value,
T>::type newObject(Args&& ... pArgs)
const
201 return internalNewObject<T>(std::forward<Args>(pArgs) ...);
205 template<
typename T,
typename ... Args>
206 T createObject(Args&& ... pArgs)
const
209 for (
auto& mock : qAsConst(mInstancesCreator))
211 auto creator =
dynamic_cast<FuncWrapper<
T, Args ...
>*>(mock.get());
214 return (*creator)(std::forward<Args>(pArgs) ...);
219 return newObject<T>(std::forward<Args>(pArgs) ...);
231 return getInstance().fetchSingleton<
T>();
235 template<
typename T,
typename ... Args>
238 return getInstance().createObject<
T>(std::forward<Args>(pArgs) ...);
245 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
246 static_assert(QtPrivate::IsGadgetHelper<T>::IsRealGadget || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
247 "Shared class needs to be a Q_GADGET or an QObject/Q_OBJECT");
249 static_assert(QtPrivate::IsGadgetHelper<T>::Value || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
250 "Shared class needs to be a Q_GADGET or an QObject/Q_OBJECT");
253 auto& holder = getInstance().mSharedInstances;
254 const auto* className = T::staticMetaObject.className();
256 QSharedPointer<T> shared = qSharedPointerCast<T>(holder.value(className));
259 shared = QSharedPointer<T>::create();
260 holder.insert(className, shared.toWeakRef());
270 static void set(
const QMetaObject& pMetaObject,
void* pObject =
nullptr);
271 static void set(
const QMetaObject& pMetaObject, std::shared_ptr<void> pObject);
273 template<
typename T,
typename U>
276 return dynamic_cast<U*
>(getSingleton<T>());
280 template<
typename T,
typename ... Args>
283 for (
const auto& mock : qAsConst(getInstance().mInstancesCreator))
285 if (
dynamic_cast<const FuncWrapper<
T, Args ...
>*>(mock.get()))
287 return mock->getCounter();
295 template<
typename T,
typename ... Args>
300 auto& holder = getInstance().mInstancesCreator;
301 const auto& value = Wrapper(
new FuncWrapper<T, Args ...>(pFunc));
303 QMutableVectorIterator<Wrapper> iter(holder);
304 while (iter.hasNext())
307 if (
dynamic_cast<const FuncWrapper<
T, Args ...
>*>(iter.value().get()))
309 iter.setValue(value);
318 static void setShared(
const QMetaObject& pMetaObject, QSharedPointer<QObject> pObject = QSharedPointer<QObject>());
static T * getSingleton()
Definition: Env.h:229
static void clear()
Definition: Env.cpp:101
static void resetCounter()
Definition: Env.cpp:92
~Env()
Definition: Env.cpp:20
static void set(const QMetaObject &pMetaObject, void *pObject=nullptr)
Definition: Env.cpp:112
T createNewObject(Args &&...pArgs)
static void setShared(const QMetaObject &pMetaObject, QSharedPointer< QObject > pObject=QSharedPointer< QObject >())
Definition: Env.cpp:129
#define T(v)
Definition: http_parser.cpp:234
static void setCreator(const std::function< T(Args...)> &pFunc)
Definition: Env.h:296
static U * getSingleton()
Definition: Env.h:274
Env()
Definition: Env.cpp:15
T * singleton(bool &pTakeOwnership)
static T create(Args &&...pArgs)
Definition: Env.h:236
static int getCounter()
Definition: Env.h:281
static QSharedPointer< T > getShared()
Definition: Env.h:243