]>
Commit | Line | Data |
---|---|---|
7db064f6 JS |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: wx/typeinfo.h | |
3 | // Purpose: wxTypeId implementation | |
4 | // Author: Jaakko Salli | |
5 | // Created: 2009-11-19 | |
7db064f6 JS |
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 | |
c81aea07 | 16 | // not implement C++ RTTI. Also, type defining macros in this file are |
7db064f6 JS |
17 | // intended for internal use only at this time and may change in future |
18 | // versions. | |
19 | // | |
c81aea07 JS |
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 | // | |
7db064f6 JS |
24 | |
25 | #include "wx/defs.h" | |
26 | ||
27 | #ifndef wxNO_RTTI | |
28 | ||
07ca69f6 JS |
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 | ||
7db064f6 JS |
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 | ||
07ca69f6 JS |
49 | #if wxTRUST_CPP_RTTI |
50 | ||
51 | #define wxTypeId typeid | |
52 | ||
53 | #else /* !wxTRUST_CPP_RTTI */ | |
54 | ||
7db064f6 JS |
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 | ||
c81aea07 | 63 | class wxTypeIdentifier |
7db064f6 JS |
64 | { |
65 | public: | |
c81aea07 | 66 | wxTypeIdentifier(const char* className) |
7db064f6 JS |
67 | { |
68 | m_className = className; | |
69 | } | |
70 | ||
c81aea07 | 71 | bool operator==(const wxTypeIdentifier& other) |
7db064f6 JS |
72 | { |
73 | return strcmp(m_className, other.m_className) == 0; | |
74 | } | |
75 | ||
c81aea07 | 76 | bool operator!=(const wxTypeIdentifier& other) |
7db064f6 JS |
77 | { |
78 | return strcmp(m_className, other.m_className) != 0; | |
79 | } | |
80 | private: | |
81 | const char* m_className; | |
82 | }; | |
83 | ||
c81aea07 | 84 | #define wxTypeId(OBJ) wxTypeIdentifier(typeid(OBJ).name()) |
7db064f6 | 85 | |
07ca69f6 JS |
86 | #endif /* wxTRUST_CPP_RTTI/!wxTRUST_CPP_RTTI */ |
87 | ||
7db064f6 JS |
88 | #else // if !wxNO_RTTI |
89 | ||
07ca69f6 JS |
90 | #define wxTRUST_CPP_RTTI 0 |
91 | ||
7db064f6 JS |
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 \ | |
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 | ||
ce00f59b | 139 | // Because abstract classes cannot be instantiated, we use |
7db064f6 JS |
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_ |