#pragma once #include "call_once.h" #include #include // from https://stackoverflow.com/questions/46172607/qt-singleton-implementation template class GenericSingelton { private: typedef T *(*CreateInstanceFunction)(); public: static T *instance(CreateInstanceFunction create); private: static void init(); GenericSingelton(); ~GenericSingelton(); Q_DISABLE_COPY(GenericSingelton) static QBasicAtomicPointer create; static QBasicAtomicInt flag; static QBasicAtomicPointer tptr; bool inited; }; template T *GenericSingelton::instance(CreateInstanceFunction create) { GenericSingelton::create.store(reinterpret_cast(create)); qCallOnce(init, flag); return (T *)tptr.load(); } template void GenericSingelton::init() { static GenericSingelton singleton; if (singleton.inited) { CreateInstanceFunction createFunction = (CreateInstanceFunction)GenericSingelton::create.load(); tptr.store(createFunction()); } } template GenericSingelton::GenericSingelton() { inited = true; } template GenericSingelton::~GenericSingelton() { T *createdTptr = (T *)tptr.fetchAndStoreOrdered(nullptr); if (createdTptr) { delete createdTptr; } create.store(nullptr); } template QBasicAtomicPointer GenericSingelton::create = Q_BASIC_ATOMIC_INITIALIZER(nullptr); template QBasicAtomicInt GenericSingelton::flag = Q_BASIC_ATOMIC_INITIALIZER(CallOnce::CO_Request); template QBasicAtomicPointer GenericSingelton::tptr = Q_BASIC_ATOMIC_INITIALIZER(nullptr);