hmbdc
simplify-high-performance-messaging-programming
GuardedSingleton.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/Exception.hpp"
5 #include <stdexcept>
6 #include <type_traits>
7 #include <typeinfo>
8 
9 namespace hmbdc { namespace pattern {
10 /**
11  * @class SingletonGuardian<>
12  * @brief RAII representing the lifespan of the underlying Singleton
13  * which also ganrantees the singularity of underlying Singleton
14  * @details when the SingletonGuardian is constructored, the underlying Singleton is created;
15  * when the SingletonGuardian goes out of scope the dtor of the Singleton is called.
16  *
17  * @tparam Singleton the underlying type, which needs to be derived from GuardedSingleton
18  */
19 template <typename Singleton>
21  template <typename...Args>
22  SingletonGuardian(Args&&...);
23  virtual ~SingletonGuardian();
24 };
25 
26 /**
27  * @class SingletonPlacementGuardian<>
28  * @brief similar to SingletonGuardian, but supports placement new of the underlying Singleton
29  * @details when the SingletonPlacementGuardian is constructored with an address,
30  * the underlying Singleton is created using placement new;
31  * when the SingletonGuardian goes out of scope the dtor of the Singleton is called properly.
32  *
33  * @tparam Singleton the underlying type, which needs to be derived from GuardedSingleton
34  */
35 template <typename Singleton>
37  template <typename...Args>
38  SingletonPlacementGuardian(void* address, Args&&...);
39 
40  SingletonPlacementGuardian(void* address);
41  virtual ~SingletonPlacementGuardian();
42 };
43 
44 /**
45  * @class GuardedSingleton<>
46  * @brief base for the Singleton that works with SingletonGuardian
47  * @details a good practice is to declare the ctor of the derived class private
48  * and friend the derived with the SingletonGuardian<derived>
49  *
50  * @tparam Singleton the derived type
51  */
52 template<typename Singleton>
54  friend struct SingletonGuardian<Singleton>;
55  friend struct SingletonPlacementGuardian<Singleton>;
56  static Singleton& instance() {return *pInstance_s;}
57  static bool initialized() {return pInstance_s;}
58  using element_type = Singleton;
59 
60 protected:
61  GuardedSingleton() = default;
62 
63 private:
64  static Singleton* pInstance_s;
65 };
66 
67 template <typename Singleton> Singleton*
69 
70 template <typename Singleton>
71 template <typename...Args>
73 SingletonGuardian(Args&&...args) {
74  if (GuardedSingleton<Singleton>::pInstance_s) {
75  HMBDC_THROW(std::runtime_error
76  , "Cannot reinitialize typeid=" << typeid(Singleton).name());
77  }
78  GuardedSingleton<Singleton>::pInstance_s
79  = new Singleton(std::forward<Args>(args)...);
80 }
81 
82 template <typename Singleton>
85  delete GuardedSingleton<Singleton>::pInstance_s;
86  GuardedSingleton<Singleton>::pInstance_s = nullptr;
87 }
88 
89 template <typename Singleton>
91 SingletonPlacementGuardian(void* addr) {
92  if (GuardedSingleton<Singleton>::pInstance_s) {
93  HMBDC_THROW(std::runtime_error
94  , "Cannot reinitialize typeid=" << typeid(Singleton).name());
95  }
96  GuardedSingleton<Singleton>::pInstance_s
97  = new (addr) Singleton;
98 }
99 
100 template <typename Singleton>
101 template <typename...Args>
103 SingletonPlacementGuardian(void* addr, Args&&...args) {
104  if (GuardedSingleton<Singleton>::pInstance_s) {
105  HMBDC_THROW(std::runtime_error
106  , "Cannot reinitialize typeid=" << typeid(Singleton).name());
107  }
108  GuardedSingleton<Singleton>::pInstance_s
109  = new (addr) Singleton{std::forward<Args>(args)...};
110 }
111 
112 template <typename Singleton>
115  GuardedSingleton<Singleton>::pInstance_s->~Singleton();
116  // ::operator delete GuardedSingleton<Singleton>::pInstance_s;
117  GuardedSingleton<Singleton>::pInstance_s = nullptr;
118 }
119 
120 }}
base for the Singleton that works with SingletonGuardian
Definition: GuardedSingleton.hpp:53
RAII representing the lifespan of the underlying Singleton which also ganrantees the singularity of u...
Definition: GuardedSingleton.hpp:20
Definition: Base.hpp:13
similar to SingletonGuardian, but supports placement new of the underlying Singleton ...
Definition: GuardedSingleton.hpp:36