Singleton.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/util/Assert.h>
  7. #include <utility>
  8. namespace anki
  9. {
  10. /// @addtogroup util_patterns
  11. /// @{
  12. /// This template makes a class singleton
  13. template<typename T>
  14. class Singleton
  15. {
  16. public:
  17. typedef T Value;
  18. // Non copyable
  19. Singleton(const Singleton&) = delete;
  20. Singleton& operator=(const Singleton&) = delete;
  21. // Non constructable
  22. Singleton() = delete;
  23. ~Singleton() = delete;
  24. /// Get instance
  25. static Value& get()
  26. {
  27. return *(m_instance ? m_instance : (m_instance = new Value));
  28. }
  29. /// Cleanup
  30. static void destroy()
  31. {
  32. if(m_instance)
  33. {
  34. delete m_instance;
  35. }
  36. }
  37. private:
  38. static Value* m_instance;
  39. };
  40. template<typename T>
  41. typename Singleton<T>::Value* Singleton<T>::m_instance = nullptr;
  42. /// This template makes a class with a destructor with arguments singleton
  43. template<typename T>
  44. class SingletonInit
  45. {
  46. public:
  47. typedef T Value;
  48. // Non copyable
  49. SingletonInit(const SingletonInit&) = delete;
  50. SingletonInit& operator=(const SingletonInit&) = delete;
  51. // Non constructable
  52. SingletonInit() = delete;
  53. ~SingletonInit() = delete;
  54. /// Init the singleton
  55. template<typename... TArgs>
  56. static void init(TArgs... args)
  57. {
  58. ANKI_ASSERT(m_instance == nullptr);
  59. m_instance = new Value(args...);
  60. }
  61. /// Get instance
  62. static Value& get()
  63. {
  64. ANKI_ASSERT(m_instance != nullptr);
  65. return *m_instance;
  66. }
  67. /// Cleanup
  68. static void destroy()
  69. {
  70. if(m_instance)
  71. {
  72. delete m_instance;
  73. }
  74. }
  75. private:
  76. static Value* m_instance;
  77. };
  78. template<typename T>
  79. typename SingletonInit<T>::Value* SingletonInit<T>::m_instance = nullptr;
  80. /// This template makes a class singleton with thread local instance
  81. template<typename T>
  82. class SingletonThreadSafe
  83. {
  84. public:
  85. typedef T Value;
  86. // Non copyable
  87. SingletonThreadSafe(const SingletonThreadSafe&) = delete;
  88. SingletonThreadSafe& operator=(const SingletonThreadSafe&) = delete;
  89. // Non constructable
  90. SingletonThreadSafe() = delete;
  91. ~SingletonThreadSafe() = delete;
  92. /// Get instance
  93. static Value& get()
  94. {
  95. return *(m_instance ? m_instance : (m_instance = new Value));
  96. }
  97. /// Cleanup
  98. void destroy()
  99. {
  100. if(m_instance)
  101. {
  102. delete m_instance;
  103. }
  104. }
  105. private:
  106. static thread_local Value* m_instance;
  107. };
  108. template<typename T>
  109. thread_local
  110. typename SingletonThreadSafe<T>::Value* SingletonThreadSafe<T>::m_instance =
  111. nullptr;
  112. /// @}
  113. } // end namespace anki