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