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