1 /////////////////////////////////////////////////////////////////////////////// 2 // Name: wx/typeinfo.h 3 // Purpose: wxTypeId implementation 4 // Author: Jaakko Salli 5 // Created: 2009-11-19 6 // Copyright: (c) wxWidgets Team 7 // Licence: wxWindows licence 8 /////////////////////////////////////////////////////////////////////////////// 9 10 #ifndef _WX_TYPEINFO_H_ 11 #define _WX_TYPEINFO_H_ 12 13 // 14 // This file defines wxTypeId macro that should be used internally in 15 // wxWidgets instead of typeid(), for compatibility with builds that do 16 // not implement C++ RTTI. Also, type defining macros in this file are 17 // intended for internal use only at this time and may change in future 18 // versions. 19 // 20 // The reason why we need this simple RTTI system in addition to the older 21 // wxObject-based one is that the latter does not work in template 22 // classes. 23 // 24 25 #include "wx/defs.h" 26 27 #ifndef wxNO_RTTI 28 29 // 30 // Let's trust that Visual C++ versions 9.0 and later implement C++ 31 // RTTI well enough, so we can use it and work around harmless memory 32 // leaks reported by the static run-time libraries. 33 // 34 #if wxCHECK_VISUALC_VERSION(9) 35 #define wxTRUST_CPP_RTTI 1 36 #else 37 #define wxTRUST_CPP_RTTI 0 38 #endif 39 40 #include <typeinfo> 41 #include <string.h> 42 43 #define _WX_DECLARE_TYPEINFO_CUSTOM(CLS, IDENTFUNC) 44 #define WX_DECLARE_TYPEINFO_INLINE(CLS) 45 #define WX_DECLARE_TYPEINFO(CLS) 46 #define WX_DEFINE_TYPEINFO(CLS) 47 #define WX_DECLARE_ABSTRACT_TYPEINFO(CLS) 48 49 #if wxTRUST_CPP_RTTI 50 51 #define wxTypeId typeid 52 53 #else /* !wxTRUST_CPP_RTTI */ 54 55 // 56 // For improved type-safety, let's make the check using class name 57 // comparison. Most modern compilers already do this, but we cannot 58 // rely on all supported compilers to work this well. However, in 59 // cases where we'd know that typeid() would be flawless (as such), 60 // wxTypeId could of course simply be defined as typeid. 61 // 62 63 class wxTypeIdentifier 64 { 65 public: wxTypeIdentifier(const char * className)66 wxTypeIdentifier(const char* className) 67 { 68 m_className = className; 69 } 70 71 bool operator==(const wxTypeIdentifier& other) const 72 { 73 return strcmp(m_className, other.m_className) == 0; 74 } 75 76 bool operator!=(const wxTypeIdentifier& other) const 77 { 78 return !(*this == other); 79 } 80 private: 81 const char* m_className; 82 }; 83 84 #define wxTypeId(OBJ) wxTypeIdentifier(typeid(OBJ).name()) 85 86 #endif /* wxTRUST_CPP_RTTI/!wxTRUST_CPP_RTTI */ 87 88 #else // if !wxNO_RTTI 89 90 #define wxTRUST_CPP_RTTI 0 91 92 // 93 // When C++ RTTI is not available, we will have to make the type comparison 94 // using pointer to a dummy static member function. This will fail if 95 // declared type is used across DLL boundaries, although using 96 // WX_DECLARE_TYPEINFO() and WX_DEFINE_TYPEINFO() pair instead of 97 // WX_DECLARE_TYPEINFO_INLINE() should fix this. However, that approach is 98 // usually not possible when type info needs to be declared for a template 99 // class. 100 // 101 102 typedef void (*wxTypeIdentifier)(); 103 104 // Use this macro to declare type info with specified static function 105 // IDENTFUNC used as type identifier. Usually you should only use 106 // WX_DECLARE_TYPEINFO() or WX_DECLARE_TYPEINFO_INLINE() however. 107 #define _WX_DECLARE_TYPEINFO_CUSTOM(CLS, IDENTFUNC) \ 108 public: \ 109 virtual wxTypeIdentifier GetWxTypeId() const wxOVERRIDE \ 110 { \ 111 return reinterpret_cast<wxTypeIdentifier> \ 112 (&IDENTFUNC); \ 113 } 114 115 // Use this macro to declare type info with externally specified 116 // type identifier, defined with WX_DEFINE_TYPEINFO(). 117 #define WX_DECLARE_TYPEINFO(CLS) \ 118 private: \ 119 static CLS sm_wxClassInfo(); \ 120 _WX_DECLARE_TYPEINFO_CUSTOM(CLS, sm_wxClassInfo) 121 122 // Use this macro to implement type identifier function required by 123 // WX_DECLARE_TYPEINFO(). 124 // NOTE: CLS is required to have default ctor. If it doesn't 125 // already, you should provide a private dummy one. 126 #define WX_DEFINE_TYPEINFO(CLS) \ 127 CLS CLS::sm_wxClassInfo() { return CLS(); } 128 129 // Use this macro to declare type info fully inline in class. 130 // NOTE: CLS is required to have default ctor. If it doesn't 131 // already, you should provide a private dummy one. 132 #define WX_DECLARE_TYPEINFO_INLINE(CLS) \ 133 private: \ 134 static CLS sm_wxClassInfo() { return CLS(); } \ 135 _WX_DECLARE_TYPEINFO_CUSTOM(CLS, sm_wxClassInfo) 136 137 #define wxTypeId(OBJ) (OBJ).GetWxTypeId() 138 139 // Because abstract classes cannot be instantiated, we use 140 // this macro to define pure virtual type interface for them. 141 #define WX_DECLARE_ABSTRACT_TYPEINFO(CLS) \ 142 public: \ 143 virtual wxTypeIdentifier GetWxTypeId() const = 0; 144 145 #endif // wxNO_RTTI/!wxNO_RTTI 146 147 #endif // _WX_TYPEINFO_H_ 148