#ifndef __HL_SINGLETONE_H #define __HL_SINGLETONE_H #include #include template class SafeSingleton { protected: static std::atomic SharedInstance; static std::mutex mMutex; public: static T& instance() { T* tmp = SharedInstance.load(std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_acquire); if (tmp == nullptr) { std::lock_guard lock(mMutex); tmp = SharedInstance.load(std::memory_order_relaxed); if (tmp == nullptr) { tmp = new T(); std::atomic_thread_fence(std::memory_order_release); SharedInstance.store(tmp, std::memory_order_relaxed); } } return *tmp; } template static T& precreate(X n) { T* tmp = SharedInstance.load(std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_acquire); if (tmp == nullptr) { std::lock_guard lock(mMutex); tmp = SharedInstance.load(std::memory_order_relaxed); if (tmp == nullptr) { tmp = new T(n); std::atomic_thread_fence(std::memory_order_release); SharedInstance.store(tmp, std::memory_order_relaxed); return *tmp; } } throw std::runtime_error("Singletone instance is created already"); } }; template std::atomic SafeSingleton::SharedInstance; template std::mutex SafeSingleton::mMutex; #endif