1 /* 2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 3 * Distributed under the MIT License 4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 5 */ 6 7 #ifndef MYGUI_SINGLETON_H_ 8 #define MYGUI_SINGLETON_H_ 9 10 #include "MyGUI_Diagnostic.h" 11 12 namespace MyGUI 13 { 14 15 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC 16 template <class T> 17 class Singleton 18 #else 19 template <class T> 20 class MYGUI_EXPORT Singleton 21 #endif 22 { 23 public: 24 using Base = Singleton<T>; 25 26 #if defined(__clang__) 27 // This constructor is called before the `T` object is fully constructed, and 28 // pointers are not dereferenced anyway, so UBSan shouldn't check vptrs. 29 __attribute__((no_sanitize("vptr"))) 30 #endif Singleton()31 Singleton() 32 { 33 MYGUI_ASSERT(nullptr == msInstance, "Singleton instance " << getClassTypeName() << " already exsist"); 34 msInstance = static_cast<T*>(this); 35 } 36 ~Singleton()37 virtual ~Singleton() 38 { 39 if (nullptr == msInstance) 40 MYGUI_LOG(Critical, "Destroying Singleton instance " << getClassTypeName() << " before constructing it."); 41 msInstance = nullptr; 42 } 43 getInstance()44 static T& getInstance() 45 { 46 MYGUI_ASSERT(nullptr != getInstancePtr(), "Singleton instance " << getClassTypeName() << " was not created"); 47 return (*getInstancePtr()); 48 } 49 getInstancePtr()50 static T* getInstancePtr() 51 { 52 return msInstance; 53 } 54 getClassTypeName()55 static const char* getClassTypeName() 56 { 57 return mClassTypeName; 58 } 59 60 private: 61 static T* msInstance; 62 static const char* mClassTypeName; 63 }; 64 65 } // namespace MyGUI 66 67 #endif // MYGUI_SINGLETON_H_ 68