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