]>
Commit | Line | Data |
---|---|---|
cc3977bf SC |
1 | /////////////////////////////////////////////////////////////////////////////\r |
2 | // Name: wx/variantbase.h\r | |
3 | // Purpose: wxVariantBase class, a minimal version of wxVariant used by XTI\r | |
4 | // Author: Julian Smart\r | |
5 | // Modified by: Francesco Montorsi\r | |
6 | // Created: 10/09/98\r | |
7 | // RCS-ID: $Id: variant.h 44625 2007-03-07 11:35:04Z VZ $\r | |
8 | // Copyright: (c) Julian Smart\r | |
9 | // Licence: wxWindows licence\r | |
10 | /////////////////////////////////////////////////////////////////////////////\r | |
11 | \r | |
12 | #ifndef _WX_VARIANTBASE_H_\r | |
13 | #define _WX_VARIANTBASE_H_\r | |
14 | \r | |
15 | #include "wx/defs.h"\r | |
16 | \r | |
17 | #if wxUSE_VARIANT\r | |
18 | \r | |
19 | #include "wx/string.h"\r | |
20 | #include "wx/arrstr.h"\r | |
21 | #include "wx/cpp.h"\r | |
22 | #include <typeinfo>\r | |
23 | \r | |
24 | #if wxUSE_DATETIME\r | |
25 | #include "wx/datetime.h"\r | |
26 | #endif // wxUSE_DATETIME\r | |
27 | \r | |
28 | #include "wx/iosfwrap.h"\r | |
29 | \r | |
30 | class wxTypeInfo;\r | |
31 | class wxObject;\r | |
32 | class wxClassInfo;\r | |
33 | \r | |
34 | /*\r | |
35 | * wxVariantData stores the actual data in a wxVariant object,\r | |
36 | * to allow it to store any type of data.\r | |
37 | * Derive from this to provide custom data handling.\r | |
38 | *\r | |
39 | * NB: To prevent addition of extra vtbl pointer to wxVariantData,\r | |
40 | * we don't multiple-inherit from wxObjectRefData. Instead,\r | |
41 | * we simply replicate the wxObject ref-counting scheme.\r | |
42 | *\r | |
43 | * NB: When you construct a wxVariantData, it will have refcount\r | |
44 | * of one. Refcount will not be further increased when\r | |
45 | * it is passed to wxVariant. This simulates old common\r | |
46 | * scenario where wxVariant took ownership of wxVariantData\r | |
47 | * passed to it.\r | |
48 | * If you create wxVariantData for other reasons than passing\r | |
49 | * it to wxVariant, technically you are not required to call\r | |
50 | * DecRef() before deleting it.\r | |
51 | *\r | |
52 | * TODO: in order to replace wxPropertyValue, we would need\r | |
53 | * to consider adding constructors that take pointers to C++ variables,\r | |
54 | * or removing that functionality from the wxProperty library.\r | |
55 | * Essentially wxPropertyValue takes on some of the wxValidator functionality\r | |
56 | * by storing pointers and not just actual values, allowing update of C++ data\r | |
57 | * to be handled automatically. Perhaps there's another way of doing this without\r | |
58 | * overloading wxVariant with unnecessary functionality.\r | |
59 | */\r | |
60 | \r | |
61 | class WXDLLIMPEXP_BASE wxVariantData\r | |
62 | {\r | |
63 | friend class wxVariantBase;\r | |
64 | \r | |
65 | public:\r | |
66 | wxVariantData()\r | |
67 | : m_count(1)\r | |
68 | { }\r | |
69 | \r | |
70 | #if wxUSE_STD_IOSTREAM\r | |
71 | virtual bool Write(wxSTD ostream& WXUNUSED(str)) const { return false; }\r | |
72 | virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }\r | |
73 | #endif\r | |
74 | virtual bool Write(wxString& WXUNUSED(str)) const { return false; }\r | |
75 | virtual bool Read(wxString& WXUNUSED(str)) { return false; }\r | |
76 | \r | |
77 | // Override these to provide common functionality\r | |
78 | virtual bool Eq(wxVariantData& data) const = 0;\r | |
79 | \r | |
80 | // What type is it? Return a string name.\r | |
81 | virtual wxString GetType() const = 0;\r | |
82 | \r | |
83 | // returns the type info of the content\r | |
84 | virtual const wxTypeInfo* GetTypeInfo() const = 0;\r | |
85 | \r | |
86 | // If it based on wxObject return the ClassInfo.\r | |
87 | virtual wxClassInfo* GetValueClassInfo() { return NULL; }\r | |
88 | \r | |
89 | int GetRefCount() const \r | |
90 | { return m_count; }\r | |
91 | void IncRef() \r | |
92 | { m_count++; }\r | |
93 | void DecRef()\r | |
94 | {\r | |
95 | if ( --m_count == 0 )\r | |
96 | delete this;\r | |
97 | }\r | |
98 | \r | |
99 | protected:\r | |
100 | // Protected dtor should make some incompatible code\r | |
101 | // break more louder. That is, they should do data->DecRef()\r | |
102 | // instead of delete data.\r | |
103 | virtual ~wxVariantData() {}\r | |
104 | \r | |
105 | private:\r | |
106 | int m_count;\r | |
107 | };\r | |
108 | \r | |
109 | template<typename T> class wxVariantDataT : public wxVariantData\r | |
110 | {\r | |
111 | public:\r | |
112 | wxVariantDataT(const T& d) : m_data(d) {}\r | |
113 | virtual ~wxVariantDataT() {}\r | |
114 | \r | |
115 | // get a ref to the stored data\r | |
116 | T & Get() { return m_data; }\r | |
117 | \r | |
118 | // get a const ref to the stored data\r | |
119 | const T & Get() const { return m_data; }\r | |
120 | \r | |
121 | // set the data\r | |
122 | void Set(const T& d) { m_data = d; }\r | |
123 | \r | |
124 | // Override these to provide common functionality\r | |
125 | virtual bool Eq(wxVariantData& WXUNUSED(data)) const\r | |
126 | { return false; /* FIXME!! */ }\r | |
127 | \r | |
128 | // What type is it? Return a string name.\r | |
129 | virtual wxString GetType() const\r | |
130 | { return GetTypeInfo()->GetTypeName(); }\r | |
131 | \r | |
132 | // return a heap allocated duplicate\r | |
133 | //virtual wxVariantData* Clone() const { return new wxVariantDataT<T>( Get() ); }\r | |
134 | \r | |
135 | // returns the type info of the contentc\r | |
136 | virtual const wxTypeInfo* GetTypeInfo() const { return wxGetTypeInfo( (T*) NULL ); }\r | |
137 | \r | |
138 | private:\r | |
139 | T m_data;\r | |
140 | };\r | |
141 | \r | |
142 | \r | |
143 | /*\r | |
144 | * wxVariantBase can store any kind of data, but has some basic types\r | |
145 | * built in.\r | |
146 | */\r | |
147 | \r | |
148 | class WXDLLIMPEXP_BASE wxVariantBase\r | |
149 | {\r | |
150 | public:\r | |
151 | wxVariantBase();\r | |
152 | wxVariantBase(const wxVariantBase& variant);\r | |
153 | wxVariantBase(wxVariantData* data, const wxString& name = wxEmptyString);\r | |
154 | \r | |
155 | template<typename T> \r | |
156 | wxVariantBase(const T& data, const wxString& name = wxEmptyString) :\r | |
157 | m_data(new wxVariantDataT<T>(data)), m_name(name) {}\r | |
158 | \r | |
159 | virtual ~wxVariantBase();\r | |
160 | \r | |
161 | // generic assignment\r | |
162 | void operator= (const wxVariantBase& variant);\r | |
163 | \r | |
164 | // Assignment using data, e.g.\r | |
165 | // myVariant = new wxStringVariantData("hello");\r | |
166 | void operator= (wxVariantData* variantData);\r | |
167 | \r | |
168 | bool operator== (const wxVariantBase& variant) const;\r | |
169 | bool operator!= (const wxVariantBase& variant) const;\r | |
170 | \r | |
171 | // Sets/gets name\r | |
172 | inline void SetName(const wxString& name) { m_name = name; }\r | |
173 | inline const wxString& GetName() const { return m_name; }\r | |
174 | \r | |
175 | // Tests whether there is data\r | |
176 | bool IsNull() const;\r | |
177 | \r | |
178 | // FIXME: used by wxVariantBase code but is nice wording...\r | |
179 | bool IsEmpty() const { return IsNull(); }\r | |
180 | \r | |
181 | // For compatibility with wxWidgets <= 2.6, this doesn't increase\r | |
182 | // reference count.\r | |
183 | wxVariantData* GetData() const { return m_data; }\r | |
184 | void SetData(wxVariantData* data) ;\r | |
185 | \r | |
186 | // make a 'clone' of the object\r | |
187 | void Ref(const wxVariantBase& clone);\r | |
188 | \r | |
189 | // destroy a reference\r | |
190 | void UnRef();\r | |
191 | \r | |
192 | // Make NULL (i.e. delete the data)\r | |
193 | void MakeNull();\r | |
194 | \r | |
195 | // write contents to a string (e.g. for debugging)\r | |
196 | wxString MakeString() const;\r | |
197 | \r | |
198 | // Delete data and name\r | |
199 | void Clear();\r | |
200 | \r | |
201 | // Returns a string representing the type of the variant,\r | |
202 | // e.g. "string", "bool", "stringlist", "list", "double", "long"\r | |
203 | wxString GetType() const;\r | |
204 | \r | |
205 | bool IsType(const wxString& type) const;\r | |
206 | bool IsValueKindOf(const wxClassInfo* type) const;\r | |
207 | \r | |
208 | // FIXME wxXTI methods:\r | |
209 | \r | |
210 | // get the typeinfo of the stored object\r | |
211 | const wxTypeInfo* GetTypeInfo() const \r | |
212 | { \r | |
213 | if (!m_data)\r | |
214 | return NULL;\r | |
215 | return m_data->GetTypeInfo(); \r | |
216 | }\r | |
217 | \r | |
218 | // get a ref to the stored data\r | |
219 | template<typename T> T& Get(wxTEMPLATED_MEMBER_FIX(T))\r | |
220 | {\r | |
221 | wxVariantDataT<T> *dataptr = \r | |
222 | wx_dynamic_cast(wxVariantDataT<T>*, m_data);\r | |
223 | wxASSERT_MSG( dataptr, \r | |
224 | wxString::Format(wxT("Cast to %s not possible"), typeid(T).name()) );\r | |
225 | return dataptr->Get();\r | |
226 | }\r | |
227 | \r | |
228 | // get a const ref to the stored data\r | |
229 | template<typename T> const T& Get(wxTEMPLATED_MEMBER_FIX(T)) const\r | |
230 | {\r | |
231 | const wxVariantDataT<T> *dataptr = \r | |
232 | wx_dynamic_cast(const wxVariantDataT<T>*, m_data);\r | |
233 | wxASSERT_MSG( dataptr, \r | |
234 | wxString::Format(wxT("Cast to %s not possible"), typeid(T).name()) );\r | |
235 | return dataptr->Get();\r | |
236 | }\r | |
237 | \r | |
238 | template<typename T> bool HasData(wxTEMPLATED_MEMBER_FIX(T)) const\r | |
239 | {\r | |
240 | const wxVariantDataT<T> *dataptr = \r | |
241 | wx_dynamic_cast(const wxVariantDataT<T>*, m_data);\r | |
242 | return dataptr != NULL;\r | |
243 | }\r | |
244 | \r | |
245 | // returns this value as string\r | |
246 | wxString GetAsString() const;\r | |
247 | \r | |
248 | // gets the stored data casted to a wxObject*, \r | |
249 | // returning NULL if cast is not possible\r | |
250 | wxObject* GetAsObject();\r | |
251 | \r | |
252 | protected:\r | |
253 | wxVariantData* m_data;\r | |
254 | wxString m_name;\r | |
255 | };\r | |
256 | \r | |
257 | #include "wx/dynarray.h"\r | |
258 | WX_DECLARE_OBJARRAY_WITH_DECL(wxVariantBase, wxVariantBaseArray, class WXDLLIMPEXP_BASE);\r | |
259 | \r | |
260 | \r | |
261 | // templated streaming, every type must have their specialization for these methods\r | |
262 | \r | |
263 | template<typename T>\r | |
264 | void wxStringReadValue( const wxString &s, T &data );\r | |
265 | \r | |
266 | template<typename T>\r | |
267 | void wxStringWriteValue( wxString &s, const T &data);\r | |
268 | \r | |
269 | template<typename T>\r | |
270 | void wxToStringConverter( const wxVariantBase &v, wxString &s wxTEMPLATED_FUNCTION_FIX(T)) \\r | |
271 | { wxStringWriteValue( s, v.wxTEMPLATED_MEMBER_CALL(Get, T) ); }\r | |
272 | \r | |
273 | template<typename T>\r | |
274 | void wxFromStringConverter( const wxString &s, wxVariantBase &v wxTEMPLATED_FUNCTION_FIX(T)) \\r | |
275 | { T d; wxStringReadValue( s, d ); v = wxVariantBase(d); }\r | |
276 | \r | |
277 | \r | |
278 | #endif // wxUSE_VARIANT\r | |
279 | #endif // _WX_VARIANTBASE_H_\r |