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