]>
Commit | Line | Data |
---|---|---|
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 | |
17 | // not implement C++ RTTI. Also, type defining macros in this file are | |
18 | // intended for internal use only at this time and may change in future | |
19 | // versions. | |
20 | // | |
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 | // | |
25 | ||
26 | #include "wx/defs.h" | |
27 | ||
28 | #ifndef wxNO_RTTI | |
29 | ||
30 | #include <typeinfo> | |
31 | #include <string.h> | |
32 | ||
33 | #define _WX_DECLARE_TYPEINFO_CUSTOM(CLS, IDENTFUNC) | |
34 | #define WX_DECLARE_TYPEINFO_INLINE(CLS) | |
35 | #define WX_DECLARE_TYPEINFO(CLS) | |
36 | #define WX_DEFINE_TYPEINFO(CLS) | |
37 | #define WX_DECLARE_ABSTRACT_TYPEINFO(CLS) | |
38 | ||
39 | // | |
40 | // For improved type-safety, let's make the check using class name | |
41 | // comparison. Most modern compilers already do this, but we cannot | |
42 | // rely on all supported compilers to work this well. However, in | |
43 | // cases where we'd know that typeid() would be flawless (as such), | |
44 | // wxTypeId could of course simply be defined as typeid. | |
45 | // | |
46 | ||
47 | class wxTypeIdentifier | |
48 | { | |
49 | public: | |
50 | wxTypeIdentifier(const char* className) | |
51 | { | |
52 | m_className = className; | |
53 | } | |
54 | ||
55 | bool operator==(const wxTypeIdentifier& other) | |
56 | { | |
57 | return strcmp(m_className, other.m_className) == 0; | |
58 | } | |
59 | ||
60 | bool operator!=(const wxTypeIdentifier& other) | |
61 | { | |
62 | return strcmp(m_className, other.m_className) != 0; | |
63 | } | |
64 | private: | |
65 | const char* m_className; | |
66 | }; | |
67 | ||
68 | #define wxTypeId(OBJ) wxTypeIdentifier(typeid(OBJ).name()) | |
69 | ||
70 | #else // if !wxNO_RTTI | |
71 | ||
72 | // | |
73 | // When C++ RTTI is not available, we will have to make the type comparison | |
74 | // using pointer to a dummy static member function. This will fail if | |
75 | // declared type is used across DLL boundaries, although using | |
76 | // WX_DECLARE_TYPEINFO() and WX_DEFINE_TYPEINFO() pair instead of | |
77 | // WX_DECLARE_TYPEINFO_INLINE() should fix this. However, that approach is | |
78 | // usually not possible when type info needs to be declared for a template | |
79 | // class. | |
80 | // | |
81 | ||
82 | typedef void (*wxTypeIdentifier)(); | |
83 | ||
84 | // Use this macro to declare type info with specified static function | |
85 | // IDENTFUNC used as type identifier. Usually you should only use | |
86 | // WX_DECLARE_TYPEINFO() or WX_DECLARE_TYPEINFO_INLINE() however. | |
87 | #define _WX_DECLARE_TYPEINFO_CUSTOM(CLS, IDENTFUNC) \ | |
88 | public: \ | |
89 | virtual wxTypeIdentifier GetWxTypeId() const \ | |
90 | { \ | |
91 | return reinterpret_cast<wxTypeIdentifier> \ | |
92 | (&IDENTFUNC); \ | |
93 | } | |
94 | ||
95 | // Use this macro to declare type info with externally specified | |
96 | // type identifier, defined with WX_DEFINE_TYPEINFO(). | |
97 | #define WX_DECLARE_TYPEINFO(CLS) \ | |
98 | private: \ | |
99 | static CLS sm_wxClassInfo(); \ | |
100 | _WX_DECLARE_TYPEINFO_CUSTOM(CLS, sm_wxClassInfo) | |
101 | ||
102 | // Use this macro to implement type identifier function required by | |
103 | // WX_DECLARE_TYPEINFO(). | |
104 | // NOTE: CLS is required to have default ctor. If it doesn't | |
105 | // already, you should provide a private dummy one. | |
106 | #define WX_DEFINE_TYPEINFO(CLS) \ | |
107 | CLS CLS::sm_wxClassInfo() { return CLS(); } | |
108 | ||
109 | // Use this macro to declare type info fully inline in class. | |
110 | // NOTE: CLS is required to have default ctor. If it doesn't | |
111 | // already, you should provide a private dummy one. | |
112 | #define WX_DECLARE_TYPEINFO_INLINE(CLS) \ | |
113 | private: \ | |
114 | static CLS sm_wxClassInfo() { return CLS(); } \ | |
115 | _WX_DECLARE_TYPEINFO_CUSTOM(CLS, sm_wxClassInfo) | |
116 | ||
117 | #define wxTypeId(OBJ) (OBJ).GetWxTypeId() | |
118 | ||
119 | // Because abstract classes cannot be instantiated, we use | |
120 | // this macro to define pure virtual type interface for them. | |
121 | #define WX_DECLARE_ABSTRACT_TYPEINFO(CLS) \ | |
122 | public: \ | |
123 | virtual wxTypeIdentifier GetWxTypeId() const = 0; | |
124 | ||
125 | #endif // wxNO_RTTI/!wxNO_RTTI | |
126 | ||
127 | #endif // _WX_TYPEINFO_H_ |