Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <mutex>
- #include <iostream>
- /////////////////////////////////////////////////////////////////////////////////
- template <typename T>
- class SingletonImpl
- {
- public:
- virtual ~SingletonImpl() { if (ms_Instance) delete ms_Instance; }
- template <typename ... Args>
- static T* GetInstance(Args... args)
- {
- if (ms_Instance)
- {
- return ms_Instance;
- }
- else
- {
- std::lock_guard<std::mutex> guard(ms_Mutex);
- if (!ms_Instance)
- {
- ms_Instance = new T(std::forward<Args>(args)...);
- }
- return ms_Instance;
- }
- }
- protected:
- static T* ms_Instance;
- static std::mutex ms_Mutex;
- };
- template <typename T>
- T* SingletonImpl<T>::ms_Instance(nullptr);
- template <typename T>
- std::mutex SingletonImpl<T>::ms_Mutex;
- /////////////////////////////////////////////////////////////////////////////////
- // Example ctor parameter for services
- struct Facade
- {
- int m_int;
- double m_double;
- char m_char;
- };
- struct ServiceManager;
- // Method for processing a single dependency
- template <typename T>
- void ProcessDependency()
- {
- ServiceManager::Get<T>(Facade());
- }
- // Class used to process all dependencies in the variadic argument pack
- template <typename T, typename ... Args>
- struct Dependencies
- {
- Dependencies() { ProcessDependencies(); }
- static void ProcessDependencies()
- {
- ProcessDependency<T>();
- Dependencies<Args...>::ProcessDependencies();
- }
- };
- // Single type specialization for handling the final argument from the pack
- template <typename T>
- struct Dependencies<T>
- {
- static void ProcessDependencies()
- {
- ProcessDependency<T>();
- }
- };
- // Example services
- struct ServiceA : public SingletonImpl<ServiceA> { ServiceA(Facade f) { std::cout << "A\n"; } };
- struct ServiceB : public SingletonImpl<ServiceB>, public Dependencies<ServiceA> { ServiceB(Facade f) { std::cout << "B\n"; } };
- struct ServiceC : public SingletonImpl<ServiceC>, public Dependencies<ServiceA, ServiceB> { ServiceC(Facade f) { std::cout << "C\n"; } };
- // Wrapper class around the getters of singleton services
- struct ServiceManager
- {
- template <typename T>
- static T* Get(Facade facade)
- {
- return T::GetInstance(facade);
- }
- };
- /////////////////////////////////////////////////////////////////////////////////
- int main()
- {
- ServiceManager::Get<ServiceC>(Facade());
- ServiceManager::Get<ServiceB>(Facade());
- ServiceManager::Get<ServiceA>(Facade());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement