Guest User

Untitled

a guest
Nov 22nd, 2017
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.38 KB | None | 0 0
  1. #include <map>
  2. #include <memory>
  3.  
  4. class AbstractInstanceContainer
  5. {
  6. public:
  7. AbstractInstanceContainer() = default;
  8. virtual ~AbstractInstanceContainer() = default;
  9.  
  10. AbstractInstanceContainer& operator=(AbstractInstanceContainer&& other) noexcept
  11. {
  12. mRawPointer = other.mRawPointer;
  13. other.mRawPointer = nullptr;
  14.  
  15. return *this;
  16. }
  17.  
  18. void* get() { return mRawPointer; }
  19.  
  20. protected:
  21. explicit AbstractInstanceContainer(void* ptr) : mRawPointer(ptr) {}
  22.  
  23. private:
  24. void* mRawPointer = nullptr;
  25. };
  26.  
  27.  
  28. template <class T>
  29. class InstanceContainer : public AbstractInstanceContainer
  30. {
  31. public:
  32. explicit InstanceContainer(std::unique_ptr<T> ptr) : AbstractInstanceContainer(ptr.get()), mPointer(std::move(ptr)) {}
  33. ~InstanceContainer() override = default;
  34.  
  35. private:
  36. std::unique_ptr<T> mPointer;
  37. };
  38.  
  39.  
  40. class ServiceContainerException
  41. {
  42. public:
  43. explicit ServiceContainerException(std::string&& message) : message(message) {}
  44.  
  45. std::string message;
  46. };
  47.  
  48. class ServiceContainer
  49. {
  50. public:
  51.  
  52. template <typename T, typename... Deps, typename... Args>
  53. void set(Args... args)
  54. {
  55. auto instance = std::make_unique<T>(get<typename std::remove_const<Deps>::type>()..., args...);
  56. std::unique_ptr<InstanceContainer<T>> service = std::make_unique<InstanceContainer<T>>(std::move(instance));
  57. mContainer[typeId<T>()] = std::move(service);
  58. }
  59.  
  60. template <typename T>
  61. T* get()
  62. {
  63. auto it = mContainer.find(typeId<T>());
  64. if (it == mContainer.end()) {
  65. throw ServiceContainerException(std::string("Service '" + std::string(typeid(T).name()) + "' not registered in container."));
  66. }
  67. // assert (it != mContainer.end());
  68.  
  69. return static_cast<T*>(it->second->get());
  70. }
  71.  
  72. private:
  73. template <typename T>
  74. int typeId()
  75. {
  76. static int id = ++mLastTypeId;
  77.  
  78. return id;
  79. }
  80.  
  81. private:
  82. static int mLastTypeId;
  83. std::map<int, std::unique_ptr<AbstractInstanceContainer>> mContainer;
  84. };
  85.  
  86. int ServiceContainer::mLastTypeId = 0;
  87.  
  88.  
  89. /***********************************************************************************************************/
  90.  
  91. #include <iostream>
  92.  
  93. struct Service1
  94. {
  95. int alpha = 0;
  96.  
  97. ~Service1() {
  98. std::cout << "Service 1 deleted" << std::endl;
  99. }
  100. };
  101.  
  102.  
  103. struct Service2
  104. {
  105. explicit Service2(Service1* s1) : s1(s1) {}
  106.  
  107. int value() { return s1->alpha; }
  108.  
  109. Service1* s1;
  110.  
  111. ~Service2() {
  112. std::cout << "Service 2 deleted" << std::endl;
  113. }
  114. };
  115.  
  116. struct Service3
  117. {
  118. Service3(Service2* s2, Service1* s1)
  119. {
  120.  
  121. }
  122. };
  123.  
  124. int main ()
  125. {
  126.  
  127. {
  128. ServiceContainer serviceContainer;
  129.  
  130. serviceContainer.set<Service1>();
  131. try {
  132. serviceContainer.set<Service3, Service2, Service1>();
  133. } catch (ServiceContainerException& e) {
  134. std::cerr << e.message << std::endl;
  135. }
  136. serviceContainer.set<Service2, Service1>(3);
  137. serviceContainer.set<Service3, Service2, Service1>();
  138.  
  139. auto s1 = serviceContainer.get<Service1>();
  140. std::cout << s1->alpha << std::endl;
  141. s1->alpha = 42;
  142. std::cout << s1->alpha << std::endl;
  143.  
  144.  
  145. auto s2 = serviceContainer.get<Service2>();
  146. std::cout << s2->value() << std::endl;
  147. s1->alpha = 36;
  148. std::cout << s2->value() << std::endl;
  149. std::cout << serviceContainer.get<Service1>()->alpha << std::endl;
  150. }
  151.  
  152. return 0;
  153. }
Add Comment
Please, Sign In to add comment