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