check for self assignment in operator=
[wxWidgets.git] / include / wx / any.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/any.h
3 // Purpose: wxAny class
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 07/05/2009
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_ANY_H_
13 #define _WX_ANY_H_
14
15 #include "wx/defs.h"
16
17 #if wxUSE_ANY
18
19 #include "wx/string.h"
20 #include "wx/meta/movable.h"
21 #include "wx/meta/if.h"
22 #include "wx/typeinfo.h"
23
24
25 // Size of the wxAny value buffer.
26 enum
27 {
28 WX_ANY_VALUE_BUFFER_SIZE = 16
29 };
30
31 union wxAnyValueBuffer
32 {
33 union Alignment
34 {
35 #if wxHAS_INT64
36 wxInt64 m_int64;
37 #endif
38 long double m_longDouble;
39 void ( *m_funcPtr )(void);
40 void ( wxAnyValueBuffer::*m_mFuncPtr )(void);
41 } m_alignment;
42
43 void* m_ptr;
44 wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
45 };
46
47 //
48 // wxAnyValueType is base class for value type functionality for C++ data
49 // types used with wxAny. Usually the default template (wxAnyValueTypeImpl<>)
50 // will create a satisfactory wxAnyValueType implementation for a data type.
51 //
52 class WXDLLIMPEXP_BASE wxAnyValueType
53 {
54 WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
55 public:
56 /**
57 Default constructor.
58 */
59 wxAnyValueType();
60
61 /**
62 Destructor.
63 */
64 virtual ~wxAnyValueType()
65 {
66 }
67
68 /**
69 This function is used for internal type matching.
70 */
71 virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
72
73 /**
74 This function is called every time the data in wxAny
75 buffer needs to be freed.
76 */
77 virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
78
79 /**
80 Implement this for buffer-to-buffer copy.
81
82 @param src
83 This is the source data buffer.
84
85 @param dst
86 This is the destination data buffer that is in either
87 uninitialized or freed state.
88 */
89 virtual void CopyBuffer(const wxAnyValueBuffer& src,
90 wxAnyValueBuffer& dst) const = 0;
91
92 /**
93 Convert value into buffer of different type. Return false if
94 not possible.
95 */
96 virtual bool ConvertValue(const wxAnyValueBuffer& src,
97 wxAnyValueType* dstType,
98 wxAnyValueBuffer& dst) const = 0;
99
100 /**
101 Use this template function for checking if wxAnyValueType represents
102 a specific C++ data type.
103
104 @remarks This template function does not work on some older compilers
105 (such as Visual C++ 6.0). For full compiler ccompatibility
106 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
107 instead.
108
109 @see wxAny::CheckType()
110 */
111 // FIXME-VC6: remove this hack when VC6 is no longer supported
112 template <typename T>
113 bool CheckType(T* reserved = NULL);
114 private:
115 };
116
117 //
118 // This method of checking the type is compatible with VC6
119 #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
120 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
121
122
123 /**
124 Helper macro for defining user value types.
125
126 Even though C++ RTTI would be fully available to use, we'd have to to
127 facilitate sub-type system which allows, for instance, wxAny with
128 signed short '15' to be treated equal to wxAny with signed long long '15'.
129 Having sm_instance is important here.
130 */
131 #define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
132 friend class wxAny; \
133 WX_DECLARE_TYPEINFO_INLINE(CLS) \
134 public: \
135 static bool IsSameClass(const wxAnyValueType* otherType) \
136 { \
137 return wxTypeId(*sm_instance) == wxTypeId(*otherType); \
138 } \
139 virtual bool IsSameType(const wxAnyValueType* otherType) const \
140 { \
141 return IsSameClass(otherType); \
142 } \
143 private: \
144 static CLS* sm_instance; \
145 public: \
146 static wxAnyValueType* GetInstance() \
147 { \
148 return sm_instance; \
149 }
150
151
152 #define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
153 CLS* CLS::sm_instance = new CLS();
154
155
156 #ifdef __VISUALC6__
157 // "non dll-interface class 'xxx' used as base interface
158 #pragma warning (push)
159 #pragma warning (disable:4275)
160 #endif
161
162 /**
163 Following are helper classes for the wxAnyValueTypeImplBase.
164 */
165 namespace wxPrivate
166 {
167
168 template<typename T>
169 class wxAnyValueTypeOpsMovable
170 {
171 public:
172 static void DeleteValue(wxAnyValueBuffer& buf)
173 {
174 wxUnusedVar(buf);
175 }
176
177 static void SetValue(const T& value,
178 wxAnyValueBuffer& buf)
179 {
180 memcpy(buf.m_buffer, &value, sizeof(T));
181 }
182
183 static const T& GetValue(const wxAnyValueBuffer& buf)
184 {
185 return *(reinterpret_cast<const T*>(&buf.m_buffer[0]));
186 }
187 };
188
189
190 template<typename T>
191 class wxAnyValueTypeOpsGeneric
192 {
193 public:
194 template<typename T2>
195 class DataHolder
196 {
197 public:
198 DataHolder(const T2& value)
199 {
200 m_value = value;
201 }
202 virtual ~DataHolder() { }
203
204 T2 m_value;
205 private:
206 wxDECLARE_NO_COPY_CLASS(DataHolder);
207 };
208
209 static void DeleteValue(wxAnyValueBuffer& buf)
210 {
211 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
212 delete holder;
213 }
214
215 static void SetValue(const T& value,
216 wxAnyValueBuffer& buf)
217 {
218 DataHolder<T>* holder = new DataHolder<T>(value);
219 buf.m_ptr = holder;
220 }
221
222 static const T& GetValue(const wxAnyValueBuffer& buf)
223 {
224 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
225 return holder->m_value;
226 }
227 };
228
229 } // namespace wxPrivate
230
231
232 /**
233 Intermediate template for the generic value type implementation.
234 We can derive from this same value type for multiple actual types
235 (for instance, we can have wxAnyValueTypeImplInt for all signed
236 integer types), and also easily implement specialized templates
237 with specific dynamic type conversion.
238 */
239 template<typename T>
240 class wxAnyValueTypeImplBase : public wxAnyValueType
241 {
242 typedef typename wxIf< wxIsMovable<T>::value &&
243 sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
244 wxPrivate::wxAnyValueTypeOpsMovable<T>,
245 wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
246 Ops;
247
248 public:
249 wxAnyValueTypeImplBase() : wxAnyValueType() { }
250 virtual ~wxAnyValueTypeImplBase() { }
251
252 virtual void DeleteValue(wxAnyValueBuffer& buf) const
253 {
254 Ops::DeleteValue(buf);
255 }
256
257 virtual void CopyBuffer(const wxAnyValueBuffer& src,
258 wxAnyValueBuffer& dst) const
259 {
260 Ops::SetValue(Ops::GetValue(src), dst);
261 }
262
263 /**
264 It is important to reimplement this in any specialized template
265 classes that inherit from wxAnyValueTypeImplBase.
266 */
267 static void SetValue(const T& value,
268 wxAnyValueBuffer& buf)
269 {
270 Ops::SetValue(value, buf);
271 }
272
273 /**
274 It is important to reimplement this in any specialized template
275 classes that inherit from wxAnyValueTypeImplBase.
276 */
277 static const T& GetValue(const wxAnyValueBuffer& buf)
278 {
279 return Ops::GetValue(buf);
280 }
281 };
282
283
284 /*
285 Generic value type template. Note that bulk of the implementation
286 resides in wxAnyValueTypeImplBase.
287 */
288 template<typename T>
289 class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
290 {
291 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
292 public:
293 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
294 virtual ~wxAnyValueTypeImpl() { }
295
296 virtual bool ConvertValue(const wxAnyValueBuffer& src,
297 wxAnyValueType* dstType,
298 wxAnyValueBuffer& dst) const
299 {
300 wxUnusedVar(src);
301 wxUnusedVar(dstType);
302 wxUnusedVar(dst);
303 return false;
304 }
305 };
306
307 template<typename T>
308 wxAnyValueTypeImpl<T>* wxAnyValueTypeImpl<T>::sm_instance =
309 new wxAnyValueTypeImpl<T>();
310
311
312 //
313 // Helper macro for using same base value type implementation for multiple
314 // actual C++ data types.
315 //
316 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
317 template<> \
318 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
319 { \
320 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
321 public: \
322 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
323 virtual ~wxAnyValueTypeImpl() { } \
324 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
325 { \
326 *(reinterpret_cast<UseDataType*>(&buf.m_buffer[0])) = \
327 static_cast<UseDataType>(value); \
328 } \
329 static T GetValue(const wxAnyValueBuffer& buf) \
330 { \
331 return static_cast<T>( \
332 *(reinterpret_cast<const UseDataType*>(&buf.m_buffer[0]))); \
333 } \
334 };
335
336
337 //
338 // Integer value types
339 //
340
341 #ifdef wxLongLong_t
342 typedef wxLongLong_t wxAnyBaseIntType;
343 typedef wxULongLong_t wxAnyBaseUintType;
344 #else
345 typedef long wxAnyBaseIntType;
346 typedef unsigned long wxAnyBaseUintType;
347 #endif
348
349
350 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
351 public wxAnyValueTypeImplBase<wxAnyBaseIntType>
352 {
353 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
354 public:
355 wxAnyValueTypeImplInt() :
356 wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
357 virtual ~wxAnyValueTypeImplInt() { }
358
359 virtual bool ConvertValue(const wxAnyValueBuffer& src,
360 wxAnyValueType* dstType,
361 wxAnyValueBuffer& dst) const;
362 };
363
364
365 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
366 public wxAnyValueTypeImplBase<wxAnyBaseUintType>
367 {
368 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
369 public:
370 wxAnyValueTypeImplUint() :
371 wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
372 virtual ~wxAnyValueTypeImplUint() { }
373
374 virtual bool ConvertValue(const wxAnyValueBuffer& src,
375 wxAnyValueType* dstType,
376 wxAnyValueBuffer& dst) const;
377 };
378
379
380 WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
381 WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
382 WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
383 WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
384 #ifdef wxLongLong_t
385 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
386 #endif
387
388 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
389 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
390 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
391 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
392 #ifdef wxLongLong_t
393 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
394 #endif
395
396
397 //
398 // String value type
399 //
400 class WXDLLIMPEXP_BASE wxAnyValueTypeImplString :
401 public wxAnyValueTypeImplBase<wxString>
402 {
403 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
404 public:
405 wxAnyValueTypeImplString() :
406 wxAnyValueTypeImplBase<wxString>() { }
407 virtual ~wxAnyValueTypeImplString() { }
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;
416
417 };
418
419 template<>
420 class wxAnyValueTypeImpl<wxString> : public wxAnyValueTypeImplString
421 {
422 public:
423 wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }
424 virtual ~wxAnyValueTypeImpl() { }
425 };
426
427
428 //
429 // Bool value type
430 //
431 template<>
432 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
433 public wxAnyValueTypeImplBase<bool>
434 {
435 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
436 public:
437 wxAnyValueTypeImpl() :
438 wxAnyValueTypeImplBase<bool>() { }
439 virtual ~wxAnyValueTypeImpl() { }
440
441 virtual bool ConvertValue(const wxAnyValueBuffer& src,
442 wxAnyValueType* dstType,
443 wxAnyValueBuffer& dst) const;
444 };
445
446 //
447 // Floating point value type
448 //
449 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
450 public wxAnyValueTypeImplBase<double>
451 {
452 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
453 public:
454 wxAnyValueTypeImplDouble() :
455 wxAnyValueTypeImplBase<double>() { }
456 virtual ~wxAnyValueTypeImplDouble() { }
457
458 virtual bool ConvertValue(const wxAnyValueBuffer& src,
459 wxAnyValueType* dstType,
460 wxAnyValueBuffer& dst) const;
461 };
462
463 // WX_ANY_DEFINE_SUB_TYPE requires this
464 typedef double wxAnyBaseDoubleType;
465
466 WX_ANY_DEFINE_SUB_TYPE(float, Double)
467 WX_ANY_DEFINE_SUB_TYPE(double, Double)
468
469
470 //
471 // Defines a dummy wxAnyValueTypeImpl<> with given export
472 // declaration. This is needed if a class is used with
473 // wxAny in both user shared library and application.
474 //
475 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
476 template<> \
477 class DECL wxAnyValueTypeImpl<CLS> : \
478 public wxAnyValueTypeImplBase<CLS> \
479 { \
480 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
481 public: \
482 wxAnyValueTypeImpl() : \
483 wxAnyValueTypeImplBase<CLS>() { } \
484 virtual ~wxAnyValueTypeImpl() { } \
485 \
486 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
487 wxAnyValueType* dstType, \
488 wxAnyValueBuffer& dst) const \
489 { \
490 wxUnusedVar(src); \
491 wxUnusedVar(dstType); \
492 wxUnusedVar(dst); \
493 return false; \
494 } \
495 };
496
497
498 // Make sure some of wx's own types get the right wxAnyValueType export
499 // (this is needed only for types that are referred to from wxBase.
500 // currently we may not use any of these types from there, but let's
501 // use the macro on at least one to make sure it compiles since we can't
502 // really test it properly in unittests since a separate DLL would
503 // be needed).
504 #if wxUSE_DATETIME
505 #include "wx/datetime.h"
506 wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
507 #endif
508
509 //#include "wx/object.h"
510 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
511
512 //#include "wx/arrstr.h"
513 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
514
515
516
517 #ifdef __VISUALC6__
518 // Re-enable useless VC6 warnings
519 #pragma warning (pop)
520 #endif
521
522
523 /*
524 Let's define a discrete Null value so we don't have to really
525 ever check if wxAny.m_type pointer is NULL or not. This is an
526 optimization, mostly. Implementation of this value type is
527 "hidden" in the source file.
528 */
529 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
530
531
532 //
533 // We need to implement custom signed/unsigned int equals operators
534 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
535 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
536 bool operator==(TS value) const \
537 { \
538 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
539 return (value == static_cast<TS> \
540 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
541 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
542 return (value == static_cast<TS> \
543 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
544 return false; \
545 } \
546 bool operator==(TUS value) const \
547 { \
548 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
549 return (value == static_cast<TUS> \
550 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
551 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
552 return (value == static_cast<TUS> \
553 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
554 return false; \
555 }
556
557
558 //
559 // The wxAny class represents a container for any type. A variant's value
560 // can be changed at run time, possibly to a different type of value.
561 //
562 // As standard, wxAny can store value of almost any type, in a fairly
563 // optimal manner even.
564 //
565 class wxAny
566 {
567 public:
568 /**
569 Default constructor.
570 */
571 wxAny()
572 {
573 m_type = wxAnyNullValueType;
574 }
575
576 /**
577 Destructor.
578 */
579 ~wxAny()
580 {
581 m_type->DeleteValue(m_buffer);
582 }
583
584 //@{
585 /**
586 Various constructors.
587 */
588 wxAny(const char* value)
589 {
590 m_type = wxAnyNullValueType;
591 Assign(wxString(value));
592 }
593 wxAny(const wchar_t* value)
594 {
595 m_type = wxAnyNullValueType;
596 Assign(wxString(value));
597 }
598
599 wxAny(const wxAny& any)
600 {
601 m_type = wxAnyNullValueType;
602 AssignAny(any);
603 }
604
605 template<typename T>
606 wxAny(const T& value)
607 {
608 m_type = wxAnyValueTypeImpl<T>::sm_instance;
609 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
610 }
611 //@}
612
613 /**
614 Use this template function for checking if this wxAny holds
615 a specific C++ data type.
616
617 @remarks This template function does not work on some older compilers
618 (such as Visual C++ 6.0). For full compiler ccompatibility
619 please use wxANY_CHECK_TYPE(any, T) macro instead.
620
621 @see wxAnyValueType::CheckType()
622 */
623 // FIXME-VC6: remove this hack when VC6 is no longer supported
624 template <typename T>
625 bool CheckType(T* = NULL)
626 {
627 return m_type->CheckType<T>();
628 }
629
630 /**
631 Returns the value type as wxAnyValueType instance.
632
633 @remarks You cannot reliably test whether two wxAnys are of
634 same value type by simply comparing return values
635 of wxAny::GetType(). Instead use
636 wxAnyValueType::CheckType<T>() template function.
637 */
638 const wxAnyValueType* GetType() const
639 {
640 return m_type;
641 }
642
643 /**
644 Tests if wxAny is null (that is, whether there is data).
645 */
646 bool IsNull() const
647 {
648 return (m_type == wxAnyNullValueType);
649 }
650
651 /**
652 Makes wxAny null (that is, clears it).
653 */
654 void MakeNull()
655 {
656 m_type->DeleteValue(m_buffer);
657 m_type = wxAnyNullValueType;
658 }
659
660 //@{
661 /**
662 Assignment operators.
663 */
664 wxAny& operator=(const wxAny &any)
665 {
666 if (this != &any)
667 AssignAny(any);
668 return *this;
669 }
670
671 template<typename T>
672 wxAny& operator=(const T &value)
673 {
674 m_type->DeleteValue(m_buffer);
675 m_type = wxAnyValueTypeImpl<T>::sm_instance;
676 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
677 return *this;
678 }
679
680 wxAny& operator=(const char* value)
681 { Assign(wxString(value)); return *this; }
682 wxAny& operator=(const wchar_t* value)
683 { Assign(wxString(value)); return *this; }
684 //@}
685
686 //@{
687 /**
688 Equality operators.
689 */
690 bool operator==(const wxString& value) const
691 {
692 if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
693 return false;
694
695 return value ==
696 static_cast<wxString>
697 (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
698 }
699
700 bool operator==(const char* value) const
701 { return (*this) == wxString(value); }
702 bool operator==(const wchar_t* value) const
703 { return (*this) == wxString(value); }
704
705 //
706 // We need to implement custom signed/unsigned int equals operators
707 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
708 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
709 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
710 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
711 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
712 #ifdef wxLongLong_t
713 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
714 #endif
715
716 bool operator==(float value) const
717 {
718 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
719 return false;
720
721 return value ==
722 static_cast<float>
723 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
724 }
725
726 bool operator==(double value) const
727 {
728 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
729 return false;
730
731 return value ==
732 static_cast<double>
733 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
734 }
735
736 bool operator==(bool value) const
737 {
738 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
739 return false;
740
741 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
742 }
743
744 //@}
745
746 //@{
747 /**
748 Inequality operators (implement as template).
749 */
750 template<typename T>
751 bool operator!=(const T& value) const
752 { return !((*this) == value); }
753 //@}
754
755 /**
756 This template function converts wxAny into given type. No dynamic
757 conversion is performed, so if the type is incorrect an assertion
758 failure will occur in debug builds, and a bogus value is returned
759 in release ones.
760
761 @remarks This template function does not work on some older compilers
762 (such as Visual C++ 6.0). For full compiler ccompatibility
763 please use wxANY_AS(any, T) macro instead.
764 */
765 // FIXME-VC6: remove this hack when VC6 is no longer supported
766 template<typename T>
767 T As(T* = NULL) const
768 {
769 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
770 {
771 wxFAIL_MSG("Incorrect or non-convertible data type");
772 }
773
774 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
775 }
776
777 /**
778 Template function that etrieves and converts the value of this
779 variant to the type that T* value is.
780
781 @return Returns @true if conversion was succesfull.
782 */
783 template<typename T>
784 bool GetAs(T* value) const
785 {
786 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
787 {
788 wxAnyValueType* otherType =
789 wxAnyValueTypeImpl<T>::sm_instance;
790 wxAnyValueBuffer temp_buf;
791
792 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
793 return false;
794
795 *value =
796 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
797 otherType->DeleteValue(temp_buf);
798
799 return true;
800 }
801 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
802 return true;
803 }
804
805 private:
806 // Assignment functions
807 void AssignAny(const wxAny& any)
808 {
809 // Must delete value - CopyBuffer() never does that
810 m_type->DeleteValue(m_buffer);
811
812 wxAnyValueType* newType = any.m_type;
813
814 if ( !newType->IsSameType(m_type) )
815 m_type = newType;
816
817 newType->CopyBuffer(any.m_buffer, m_buffer);
818 }
819
820 template<typename T>
821 void Assign(const T &value)
822 {
823 m_type->DeleteValue(m_buffer);
824 m_type = wxAnyValueTypeImpl<T>::sm_instance;
825 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
826 }
827
828 // Data
829 wxAnyValueBuffer m_buffer;
830 wxAnyValueType* m_type;
831 };
832
833
834 //
835 // This method of checking the type is compatible with VC6
836 #define wxANY_CHECK_TYPE(any, T) \
837 wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)
838
839
840 //
841 // This method of getting the value is compatible with VC6
842 #define wxANY_AS(any, T) \
843 any.As(static_cast<T*>(NULL))
844
845
846 template<typename T>
847 inline bool wxAnyValueType::CheckType(T* reserved)
848 {
849 wxUnusedVar(reserved);
850 return wxAnyValueTypeImpl<T>::IsSameClass(this);
851 }
852
853
854
855 #endif // wxUSE_ANY
856
857 #endif // _WX_ANY_H_