Advertisement
Guest User

Dependencies

a guest
Feb 27th, 2020
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.40 KB | None | 0 0
  1. #include <mutex>
  2. #include <iostream>
  3.  
  4. /////////////////////////////////////////////////////////////////////////////////
  5.  
  6. template <typename T>
  7. class SingletonImpl
  8. {
  9. public:
  10.     virtual ~SingletonImpl() { if (ms_Instance) delete ms_Instance; }
  11.  
  12.     template <typename ... Args>
  13.     static T* GetInstance(Args... args)
  14.     {
  15.         if (ms_Instance)
  16.         {
  17.             return ms_Instance;
  18.         }
  19.         else
  20.         {
  21.             std::lock_guard<std::mutex> guard(ms_Mutex);
  22.  
  23.             if (!ms_Instance)
  24.             {
  25.                 ms_Instance = new T(std::forward<Args>(args)...);
  26.             }
  27.  
  28.             return ms_Instance;
  29.         }
  30.     }
  31.  
  32. protected:
  33.     static T* ms_Instance;
  34.     static std::mutex ms_Mutex;
  35. };
  36.  
  37. template <typename T>
  38. T* SingletonImpl<T>::ms_Instance(nullptr);
  39.  
  40. template <typename T>
  41. std::mutex SingletonImpl<T>::ms_Mutex;
  42.  
  43. /////////////////////////////////////////////////////////////////////////////////
  44.  
  45. // Example ctor parameter for services
  46. struct Facade
  47. {
  48.     int m_int;
  49.     double m_double;
  50.     char m_char;
  51. };
  52.  
  53. struct ServiceManager;
  54.  
  55. // Method for processing a single dependency
  56. template <typename T>
  57. void ProcessDependency()
  58. {
  59.     ServiceManager::Get<T>(Facade());
  60. }
  61.  
  62. // Class used to process all dependencies in the variadic argument pack
  63. template <typename T, typename ... Args>
  64. struct Dependencies
  65. {
  66.     Dependencies() { ProcessDependencies(); }
  67.  
  68.     static void ProcessDependencies()
  69.     {
  70.         ProcessDependency<T>();
  71.         Dependencies<Args...>::ProcessDependencies();
  72.     }
  73. };
  74.  
  75. // Single type specialization for handling the final argument from the pack
  76. template <typename T>
  77. struct Dependencies<T>
  78. {
  79.     static void ProcessDependencies()
  80.     {
  81.         ProcessDependency<T>();
  82.     }
  83. };
  84.  
  85. // Example services
  86. struct ServiceA : public SingletonImpl<ServiceA> { ServiceA(Facade f) { std::cout << "A\n"; } };
  87. struct ServiceB : public SingletonImpl<ServiceB>, public Dependencies<ServiceA> { ServiceB(Facade f) { std::cout << "B\n"; } };
  88. struct ServiceC : public SingletonImpl<ServiceC>, public Dependencies<ServiceA, ServiceB> { ServiceC(Facade f) { std::cout << "C\n"; } };
  89.  
  90. // Wrapper class around the getters of singleton services
  91. struct ServiceManager
  92. {
  93.     template <typename T>
  94.     static T* Get(Facade facade)
  95.     {
  96.         return T::GetInstance(facade);
  97.     }
  98. };
  99.  
  100.  
  101. /////////////////////////////////////////////////////////////////////////////////
  102.  
  103. int main()
  104. {
  105.     ServiceManager::Get<ServiceC>(Facade());
  106.     ServiceManager::Get<ServiceB>(Facade());
  107.     ServiceManager::Get<ServiceA>(Facade());
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement