fork(2) download
  1. #include <type_traits>
  2. #include <exception>
  3.  
  4. class NonCopyable
  5. {
  6. public:
  7. NonCopyable(const NonCopyable&) = delete;
  8. NonCopyable(NonCopyable&&) = delete;
  9. NonCopyable& operator=(const NonCopyable&) = delete;
  10. NonCopyable& operator=(NonCopyable&&) = delete;
  11. ~NonCopyable() = default;
  12. protected:
  13. NonCopyable() = default;
  14. };
  15.  
  16. template <typename T>
  17. class Subsystem : NonCopyable
  18. {
  19. public:
  20. template<class ...Args>
  21. static bool Create(Args&& ...args)
  22. {
  23. if( IsValid() )
  24. throw ("Trying to create an already created module.");
  25.  
  26. instance() = new T(std::forward<Args>(args)...);
  27. isCreate() = true;
  28. return IsValid();
  29. }
  30.  
  31. template<typename SubClass, class ...Args>
  32. static bool Create(Args&& ...args)
  33. {
  34. if( IsValid() )
  35. throw ("Trying to create an already created module.");
  36.  
  37. instance() = static_cast<T*>(new SubClass(std::forward<Args>(args)...));
  38. isCreate() = true;
  39. return IsValid();
  40. }
  41.  
  42. static void Destroy()
  43. {
  44. delete instance();
  45. valid() = false;
  46. isCreate() = false;
  47. }
  48.  
  49. static T& Get()
  50. {
  51. if( !IsValid() )
  52. throw ("Trying to access a module but it hasn't been created up yet.");
  53.  
  54. return *instance();
  55. }
  56.  
  57. static const bool IsValid()
  58. {
  59. return valid() && isCreate();
  60. }
  61.  
  62. protected:
  63. Subsystem() = default;
  64. ~Subsystem() = default;
  65.  
  66. static T*& instance()
  67. {
  68. static T* inst = nullptr;
  69. return inst;
  70. }
  71.  
  72. static bool& valid()
  73. {
  74. static bool inst = false;
  75. return inst;
  76. }
  77.  
  78. static bool& isCreate()
  79. {
  80. static bool inst = false;
  81. return inst;
  82. }
  83.  
  84. static void setValid(bool bvalid)
  85. {
  86. valid() = bvalid;
  87. }
  88. };
  89.  
  90. template <typename T>
  91. inline T& GetSubsystem()
  92. {
  93. return T::Get();
  94. }
  95.  
  96. class Foo1 : public Subsystem<Foo1>
  97. {
  98. public:
  99. Foo1(int ni) : i(ni)
  100. {
  101. if (i == 0)
  102. return;
  103. setValid(true);
  104. }
  105. int i;
  106.  
  107. void Bar(){i = i + 10;}
  108. };
  109.  
  110. class Foo2 : public Subsystem<Foo2>
  111. {
  112. public:
  113. Foo2(int nx, int ny) : x(nx), y(ny) {setValid(true);}
  114. int x,y;
  115. };
  116.  
  117. class Foo3 : public Subsystem<Foo3>
  118. {
  119. public:
  120. Foo3(float nf) : f(nf) {setValid(true);}
  121. float f;
  122. };
  123.  
  124. int main()
  125. {
  126. Foo1::Create(10);
  127. Foo2::Create(10,20);
  128. Foo3::Create(10.4f);
  129.  
  130.  
  131. GetSubsystem<Foo1>().Bar();
  132.  
  133.  
  134. Foo3::Destroy();
  135. Foo2::Destroy();
  136. Foo1::Destroy();
  137.  
  138. return 0;
  139. }
Success #stdin #stdout 0s 4508KB
stdin
Standard input is empty
stdout
Standard output is empty