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