To work around harmless memory leaks reported by Visual C++ static runtime libs,...
[wxWidgets.git] / include / wx / typeinfo.h
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 //
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
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
50 #if wxTRUST_CPP_RTTI
51
52 #define wxTypeId typeid
53
54 #else /* !wxTRUST_CPP_RTTI */
55
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
64 class wxTypeIdentifier
65 {
66 public:
67 wxTypeIdentifier(const char* className)
68 {
69 m_className = className;
70 }
71
72 bool operator==(const wxTypeIdentifier& other)
73 {
74 return strcmp(m_className, other.m_className) == 0;
75 }
76
77 bool operator!=(const wxTypeIdentifier& other)
78 {
79 return strcmp(m_className, other.m_className) != 0;
80 }
81 private:
82 const char* m_className;
83 };
84
85 #define wxTypeId(OBJ) wxTypeIdentifier(typeid(OBJ).name())
86
87 #endif /* wxTRUST_CPP_RTTI/!wxTRUST_CPP_RTTI */
88
89 #else // if !wxNO_RTTI
90
91 #define wxTRUST_CPP_RTTI 0
92
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
140 // Because abstract classes cannot be instantiated, we use
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_