qxLib
singleton.inl
Go to the documentation of this file.
1 /**
2 
3  @file singleton.inl
4  @author Khrapov
5  @date 19.09.2025
6  @copyright © Nick Khrapov, 2025. All right reserved.
7 
8 **/
9 
10 namespace qx
11 {
12 
13 inline singletons_manager::~singletons_manager() noexcept
14 {
15  while (!m_Singletons.empty())
16  m_Singletons.pop_back();
17 }
18 
19 inline singletons_manager& singletons_manager::get_instance() noexcept
20 {
21  static singletons_manager instance;
22  return instance;
23 }
24 
25 inline void singletons_manager::add(std::unique_ptr<base_singleton> pSingleton) noexcept
26 {
27  std::lock_guard _(m_SingletonsMutex);
28  m_Singletons.push_back(std::move(pSingleton));
29 }
30 
31 template<class T, class... dependencies_t>
32  requires(std::is_base_of_v<base_singleton, dependencies_t> && ...)
33 T& singleton<T, dependencies_t...>::get_instance()
34 {
35  static_assert(
36  std::is_final_v<T>,
37  "T must be final in order qx::singleton to be safely used with multiple inheritance");
38 
39  static std::mutex instanceMutex;
40  std::lock_guard _(instanceMutex);
41 
42  static T* pSavedInstance = nullptr;
43  if (!pSavedInstance) [[unlikely]]
44  {
45  (dependencies_t::get_instance(), ...);
46 
47  std::unique_ptr<T> pInstance = std::make_unique<T>();
48  pInstance->init();
49  pSavedInstance = pInstance.get();
50  singletons_manager::get_instance().add(std::move(pInstance));
51  }
52 
53  return *pSavedInstance;
54 }
55 
56 template<class T, class... dependencies_t>
57  requires(std::is_base_of_v<base_singleton, dependencies_t> && ...)
58 void singleton<T, dependencies_t...>::init()
59 {
60 }
61 
62 } // namespace qx
Inherit the necessary singleton class from this.
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
Definition: coalesce.inl:57