]> git.saurik.com Git - wxWidgets.git/blob - interface/wx/any.h
Make storing non-trivial data in wxThreadSpecificInfo possible.
[wxWidgets.git] / interface / wx / any.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: any.h
3 // Purpose: interface of wxAny
4 // Author: wxWidgets team
5 // Licence: wxWindows licence
6 /////////////////////////////////////////////////////////////////////////////
7
8
9 /**
10 @class wxAny
11
12 The wxAny class represents a container for any type. Its value
13 can be changed at run time, possibly to a different type of value.
14
15 wxAny is a backwards-incompatible (but convertible) successor class for
16 wxVariant, essentially doing the same thing in a more modern, template-
17 based manner and with transparent support for any user data type.
18
19 Some pseudo-code'ish example of use with arbitrary user data:
20
21 @code
22 void SomeFunction()
23 {
24 MyClass myObject;
25 wxAny any = myObject;
26
27 // Do something
28 // ...
29
30 // Let's do a sanity check to make sure that any still holds
31 // data of correct type.
32 if ( any.CheckType<MyClass>() )
33 {
34 // Thank goodness, still a correct type.
35 MyClass myObject2 = any.As<MyClass>();
36 }
37 else
38 {
39 // Something has gone horribly wrong!
40 wxFAIL();
41 }
42 }
43 @endcode
44
45 When compared to wxVariant, there are various internal implementation
46 differences as well. For instance, wxAny only allocates separate data
47 object in heap for large objects (i.e. ones with size more than
48 WX_ANY_VALUE_BUFFER_SIZE, which at the time of writing is 16 bytes).
49
50 @note When performing conversions between strings and floating point
51 numbers, the representation of numbers in C locale is always used.
52 I.e. @code wxAny("1.23").GetAs<double>() @endcode will always work,
53 even if the current locale uses comma as decimal separator.
54
55 @library{wxbase}
56 @category{data}
57
58 @see wxAnyValueType, wxVariant, @ref overview_cpp_rtti_disabled
59 */
60 class wxAny
61 {
62 public:
63 /**
64 Default constructor. It seeds the object with a null value.
65 */
66 wxAny();
67
68 /**
69 Constructs wxAny from data.
70 */
71 template<typename T>
72 wxAny(const T& value);
73
74 /**
75 Constructs wxAny from another wxAny.
76 */
77 wxAny(const wxAny& any);
78
79 /**
80 Constructs wxAny, converting value from wxVariant.
81
82 @remarks Because of this conversion, it is not usually possible to
83 have wxAny that actually holds a wxVariant. If wxVariant
84 cannot be converted to a specific data type, wxAny will then
85 hold and manage reference to wxVariantData* similar to how
86 wxVariant does.
87 */
88 wxAny(const wxVariant& variant);
89
90 /**
91 Destructor.
92 */
93 ~wxAny();
94
95 /**
96 This template function converts wxAny into given type. In most cases
97 no type conversion is performed, so if the type is incorrect an
98 assertion failure will occur.
99
100 @remarks For conveniency, conversion is done when T is wxString. This
101 is useful when a string literal (which are treated as
102 const char* and const wchar_t*) has been assigned to wxAny.
103
104 This template function may not work properly with Visual C++
105 6. For full compiler compatibility, please use
106 wxANY_AS(any, T) macro instead.
107 */
108 template<typename T>
109 T As() const;
110
111 /**
112 Use this template function for checking if this wxAny holds
113 a specific C++ data type.
114
115 @remarks This template function may not work properly with Visual C++
116 6. For full compiler compatibility, please use
117 wxANY_CHECK_TYPE(any, T) macro instead.
118
119 @see wxAnyValueType::CheckType()
120 */
121 template<typename T>
122 bool CheckType() const;
123
124 /**
125 Template function that retrieves and converts the value of this
126 wxAny to the type that T* value is.
127
128 @return Returns @true if conversion was successful.
129 */
130 template<typename T>
131 bool GetAs(T* value) const;
132
133 /**
134 Specialization of GetAs() that allows conversion of wxAny into
135 wxVariant.
136
137 @return Returns @true if conversion was successful. Conversion usually
138 only fails if variant used custom wxVariantData that did not
139 implement the wxAny to wxVariant conversion functions.
140 */
141 bool GetAs(wxVariant* value) const;
142
143 /**
144 Returns the value type as wxAnyValueType instance.
145
146 @remarks You cannot reliably test whether two wxAnys are of
147 same value type by simply comparing return values
148 of wxAny::GetType(). Instead, use wxAny::HasSameType().
149
150 @see HasSameType()
151 */
152 const wxAnyValueType* GetType() const;
153
154 /**
155 Returns @true if this and another wxAny have the same
156 value type.
157 */
158 bool HasSameType(const wxAny& other) const;
159
160 /**
161 Tests if wxAny is null (that is, whether there is no data).
162 */
163 bool IsNull() const;
164
165 /**
166 Makes wxAny null (that is, clears it).
167 */
168 void MakeNull();
169
170 //@{
171 /**
172 @name Assignment operators
173 */
174 template<typename T>
175 wxAny& operator=(const T &value);
176 wxAny& operator=(const wxAny &any);
177 wxAny& operator=(const wxVariant &variant);
178 //@}
179
180 //@{
181 /**
182 @name Equality operators
183
184 @remarks Generic template-based comparison operators have not been
185 provided for various code consistency reasons, so for custom
186 data types you have do something like this:
187
188 @code
189 if ( any.CheckType<MyClass*>() &&
190 any.As<MyClass*>() == myObjectPtr )
191 {
192 // Do something if any stores myObjectPtr
193 }
194 @endcode
195 */
196 bool operator==(signed char value) const;
197 bool operator==(signed short value) const;
198 bool operator==(signed int value) const;
199 bool operator==(signed long value) const;
200 bool operator==(wxLongLong_t value) const;
201 bool operator==(unsigned char value) const;
202 bool operator==(unsigned short value) const;
203 bool operator==(unsigned int value) const;
204 bool operator==(unsigned long value) const;
205 bool operator==(wxULongLong_t value) const;
206 bool operator==(float value) const;
207 bool operator==(double value) const;
208 bool operator==(bool value) const;
209 bool operator==(const char* value) const;
210 bool operator==(const wchar_t* value) const;
211 bool operator==(const wxString& value) const;
212 //@}
213
214 //@{
215 /**
216 @name Inequality operators
217 */
218 bool operator!=(signed char value) const;
219 bool operator!=(signed short value) const;
220 bool operator!=(signed int value) const;
221 bool operator!=(signed long value) const;
222 bool operator!=(wxLongLong_t value) const;
223 bool operator!=(unsigned char value) const;
224 bool operator!=(unsigned short value) const;
225 bool operator!=(unsigned int value) const;
226 bool operator!=(unsigned long value) const;
227 bool operator!=(wxULongLong_t value) const;
228 bool operator!=(float value) const;
229 bool operator!=(double value) const;
230 bool operator!=(bool value) const;
231 bool operator!=(const char* value) const;
232 bool operator!=(const wchar_t* value) const;
233 bool operator!=(const wxString& value) const;
234 //@}
235 };
236
237 /**
238 This is value getter macro that is more compatible with older
239 compilers, such as Visual C++ 6.0.
240 */
241 #define wxANY_AS(any, T)
242
243
244 /**
245 This is type checking macro that is more compatible with older
246 compilers, such as Visual C++ 6.0.
247 */
248 #define wxANY_CHECK_TYPE(any, T)
249
250
251 /**
252 Size of the wxAny value buffer.
253 */
254 enum
255 {
256 WX_ANY_VALUE_BUFFER_SIZE = 16
257 };
258
259 /**
260 Type for buffer within wxAny for holding data.
261 */
262 union wxAnyValueBuffer
263 {
264 void* m_ptr;
265 wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
266 };
267
268
269 /**
270 @class wxAnyValueType
271
272 wxAnyValueType is base class for value type functionality for C++ data
273 types used with wxAny. Usually the default template will create a
274 satisfactory wxAnyValueType implementation for a data type, but
275 sometimes you may need to add some customization. To do this you will need
276 to add specialized template of wxAnyValueTypeImpl<>. Often your only
277 need may be to add dynamic type conversion which would be done like
278 this:
279
280 @code
281 template<>
282 class wxAnyValueTypeImpl<MyClass> :
283 public wxAnyValueTypeImplBase<MyClass>
284 {
285 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
286 public:
287 wxAnyValueTypeImpl() :
288 wxAnyValueTypeImplBase<MyClass>() { }
289 virtual ~wxAnyValueTypeImpl() { }
290
291 virtual bool ConvertValue(const wxAnyValueBuffer& src,
292 wxAnyValueType* dstType,
293 wxAnyValueBuffer& dst) const
294 {
295 // GetValue() is a static member function implemented
296 // in wxAnyValueTypeImplBase<>.
297 MyClass value = GetValue(src);
298
299 // TODO: Convert value from src buffer to destination
300 // type and buffer. If cannot be done, return
301 // false. This is a simple sample.
302 if ( dstType->CheckType<wxString>() )
303 {
304 wxString s = value.ToString();
305 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
306 }
307 else
308 {
309 return false;
310 }
311 }
312 };
313
314 //
315 // Following must be placed somewhere in your source code
316 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
317 @endcode
318
319 wxAnyValueTypeImplBase<> template, from which we inherit in the above
320 example, contains the bulk of the default wxAnyValueTypeImpl<> template
321 implementation, and as such allows you to easily add some minor
322 customization.
323
324 If you need a have complete control over the type interpretation, you
325 will need to derive a class directly from wxAnyValueType, like this:
326
327 @code
328 template <>
329 class wxAnyValueTypeImpl<MyClass> : public wxAnyValueType
330 {
331 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
332 public:
333 virtual void DeleteValue(wxAnyValueBuffer& buf) const
334 {
335 // TODO: Free the data in buffer
336 // It is important to clear the buffer like this
337 // at the end of DeleteValue().
338 buf.m_ptr = NULL;
339 }
340
341 virtual void CopyBuffer(const wxAnyValueBuffer& src,
342 wxAnyValueBuffer& dst) const
343 {
344 // TODO: Copy value from one buffer to another.
345 // dst is already uninitialized and does not
346 // need to be freed.
347 }
348
349 virtual bool ConvertValue(const wxAnyValueBuffer& src,
350 wxAnyValueType* dstType,
351 wxAnyValueBuffer& dst) const
352 {
353 // TODO: Convert value from src buffer to destination
354 // type and buffer.
355 }
356
357 //
358 // Following static functions must be implemented
359 //
360
361 static void SetValue(const T& value,
362 wxAnyValueBuffer& buf)
363 {
364 // TODO: Store value into buf.
365 }
366
367 static const T& GetValue(const wxAnyValueBuffer& buf)
368 {
369 // TODO: Return reference to value stored in buffer.
370 }
371 };
372
373 //
374 // Following must be placed somewhere in your source code
375 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
376
377 @endcode
378
379 @library{wxbase}
380 @category{data}
381
382 @see wxAny
383 */
384 class wxAnyValueType
385 {
386 public:
387 /**
388 Default constructor.
389 */
390 wxAnyValueType();
391
392 /**
393 Destructor.
394 */
395 virtual ~wxAnyValueType();
396
397 /**
398 Use this template function for checking if wxAnyValueType represents
399 a specific C++ data type.
400
401 @remarks This template function does not work on some older compilers
402 (such as Visual C++ 6.0). For full compiler compatibility
403 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
404 instead.
405
406 @see wxAny::CheckType()
407 */
408 template <typename T>
409 bool CheckType() const;
410
411 /**
412 Convert value into buffer of different type. Return false if
413 not possible.
414 */
415 virtual bool ConvertValue(const wxAnyValueBuffer& src,
416 wxAnyValueType* dstType,
417 wxAnyValueBuffer& dst) const = 0;
418
419 /**
420 Implement this for buffer-to-buffer copy.
421
422 @param src
423 This is the source data buffer.
424
425 @param dst
426 This is the destination data buffer that is in either
427 uninitialized or freed state.
428 */
429 virtual void CopyBuffer(const wxAnyValueBuffer& src,
430 wxAnyValueBuffer& dst) const = 0;
431
432 /**
433 This function is called every time the data in wxAny
434 buffer needs to be freed.
435 */
436 virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
437
438 /**
439 This function is used for internal type matching.
440 */
441 virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
442 };
443
444 /**
445 This is type checking macro that is more compatible with older
446 compilers, such as Visual C++ 6.0.
447 */
448 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T)