Fixed VC6 compilation - wxAny(const wxVariant&) ctor required a specific 'template<>')
[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 // Breaking this code into two lines should supress
186 // GCC's 'type-punned pointer will break strict-aliasing rules'
187 // warning.
188 const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
189 return *value;
190 }
191 };
192
193
194 template<typename T>
195 class wxAnyValueTypeOpsGeneric
196 {
197 public:
198 template<typename T2>
199 class DataHolder
200 {
201 public:
202 DataHolder(const T2& value)
203 {
204 m_value = value;
205 }
206 virtual ~DataHolder() { }
207
208 T2 m_value;
209 private:
210 wxDECLARE_NO_COPY_CLASS(DataHolder);
211 };
212
213 static void DeleteValue(wxAnyValueBuffer& buf)
214 {
215 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
216 delete holder;
217 }
218
219 static void SetValue(const T& value,
220 wxAnyValueBuffer& buf)
221 {
222 DataHolder<T>* holder = new DataHolder<T>(value);
223 buf.m_ptr = holder;
224 }
225
226 static const T& GetValue(const wxAnyValueBuffer& buf)
227 {
228 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
229 return holder->m_value;
230 }
231 };
232
233 } // namespace wxPrivate
234
235
236 /**
237 Intermediate template for the generic value type implementation.
238 We can derive from this same value type for multiple actual types
239 (for instance, we can have wxAnyValueTypeImplInt for all signed
240 integer types), and also easily implement specialized templates
241 with specific dynamic type conversion.
242 */
243 template<typename T>
244 class wxAnyValueTypeImplBase : public wxAnyValueType
245 {
246 typedef typename wxIf< wxIsMovable<T>::value &&
247 sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
248 wxPrivate::wxAnyValueTypeOpsMovable<T>,
249 wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
250 Ops;
251
252 public:
253 wxAnyValueTypeImplBase() : wxAnyValueType() { }
254 virtual ~wxAnyValueTypeImplBase() { }
255
256 virtual void DeleteValue(wxAnyValueBuffer& buf) const
257 {
258 Ops::DeleteValue(buf);
259 }
260
261 virtual void CopyBuffer(const wxAnyValueBuffer& src,
262 wxAnyValueBuffer& dst) const
263 {
264 Ops::SetValue(Ops::GetValue(src), dst);
265 }
266
267 /**
268 It is important to reimplement this in any specialized template
269 classes that inherit from wxAnyValueTypeImplBase.
270 */
271 static void SetValue(const T& value,
272 wxAnyValueBuffer& buf)
273 {
274 Ops::SetValue(value, buf);
275 }
276
277 /**
278 It is important to reimplement this in any specialized template
279 classes that inherit from wxAnyValueTypeImplBase.
280 */
281 static const T& GetValue(const wxAnyValueBuffer& buf)
282 {
283 return Ops::GetValue(buf);
284 }
285 };
286
287
288 /*
289 Generic value type template. Note that bulk of the implementation
290 resides in wxAnyValueTypeImplBase.
291 */
292 template<typename T>
293 class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
294 {
295 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
296 public:
297 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
298 virtual ~wxAnyValueTypeImpl() { }
299
300 virtual bool ConvertValue(const wxAnyValueBuffer& src,
301 wxAnyValueType* dstType,
302 wxAnyValueBuffer& dst) const
303 {
304 wxUnusedVar(src);
305 wxUnusedVar(dstType);
306 wxUnusedVar(dst);
307 return false;
308 }
309 };
310
311 template<typename T>
312 wxAnyValueTypeImpl<T>* wxAnyValueTypeImpl<T>::sm_instance =
313 new wxAnyValueTypeImpl<T>();
314
315
316 //
317 // Helper macro for using same base value type implementation for multiple
318 // actual C++ data types.
319 //
320 #define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
321 template<> \
322 class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
323 { \
324 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
325 public: \
326 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
327 virtual ~wxAnyValueTypeImpl() { } \
328 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
329 { \
330 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
331 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
332 *dptr = static_cast<UseDataType>(value); \
333 } \
334 static T GetValue(const wxAnyValueBuffer& buf) \
335 { \
336 const void* voidPtr = \
337 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
338 const UseDataType* sptr = \
339 reinterpret_cast<const UseDataType*>(voidPtr); \
340 return static_cast<T>(*sptr); \
341 } \
342 };
343
344
345 //
346 // Integer value types
347 //
348
349 #ifdef wxLongLong_t
350 typedef wxLongLong_t wxAnyBaseIntType;
351 typedef wxULongLong_t wxAnyBaseUintType;
352 #else
353 typedef long wxAnyBaseIntType;
354 typedef unsigned long wxAnyBaseUintType;
355 #endif
356
357
358 class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
359 public wxAnyValueTypeImplBase<wxAnyBaseIntType>
360 {
361 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
362 public:
363 wxAnyValueTypeImplInt() :
364 wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
365 virtual ~wxAnyValueTypeImplInt() { }
366
367 virtual bool ConvertValue(const wxAnyValueBuffer& src,
368 wxAnyValueType* dstType,
369 wxAnyValueBuffer& dst) const;
370 };
371
372
373 class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
374 public wxAnyValueTypeImplBase<wxAnyBaseUintType>
375 {
376 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
377 public:
378 wxAnyValueTypeImplUint() :
379 wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
380 virtual ~wxAnyValueTypeImplUint() { }
381
382 virtual bool ConvertValue(const wxAnyValueBuffer& src,
383 wxAnyValueType* dstType,
384 wxAnyValueBuffer& dst) const;
385 };
386
387
388 WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
389 WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
390 WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
391 WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
392 #ifdef wxLongLong_t
393 WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
394 #endif
395
396 WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
397 WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
398 WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
399 WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
400 #ifdef wxLongLong_t
401 WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
402 #endif
403
404
405 //
406 // String value type
407 //
408 class WXDLLIMPEXP_BASE wxAnyValueTypeImplString :
409 public wxAnyValueTypeImplBase<wxString>
410 {
411 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
412 public:
413 wxAnyValueTypeImplString() :
414 wxAnyValueTypeImplBase<wxString>() { }
415 virtual ~wxAnyValueTypeImplString() { }
416
417 /**
418 Convert value into buffer of different type. Return false if
419 not possible.
420 */
421 virtual bool ConvertValue(const wxAnyValueBuffer& src,
422 wxAnyValueType* dstType,
423 wxAnyValueBuffer& dst) const;
424
425 };
426
427 template<>
428 class wxAnyValueTypeImpl<wxString> : public wxAnyValueTypeImplString
429 {
430 public:
431 wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }
432 virtual ~wxAnyValueTypeImpl() { }
433 };
434
435
436 //
437 // Bool value type
438 //
439 template<>
440 class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
441 public wxAnyValueTypeImplBase<bool>
442 {
443 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
444 public:
445 wxAnyValueTypeImpl() :
446 wxAnyValueTypeImplBase<bool>() { }
447 virtual ~wxAnyValueTypeImpl() { }
448
449 virtual bool ConvertValue(const wxAnyValueBuffer& src,
450 wxAnyValueType* dstType,
451 wxAnyValueBuffer& dst) const;
452 };
453
454 //
455 // Floating point value type
456 //
457 class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
458 public wxAnyValueTypeImplBase<double>
459 {
460 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
461 public:
462 wxAnyValueTypeImplDouble() :
463 wxAnyValueTypeImplBase<double>() { }
464 virtual ~wxAnyValueTypeImplDouble() { }
465
466 virtual bool ConvertValue(const wxAnyValueBuffer& src,
467 wxAnyValueType* dstType,
468 wxAnyValueBuffer& dst) const;
469 };
470
471 // WX_ANY_DEFINE_SUB_TYPE requires this
472 typedef double wxAnyBaseDoubleType;
473
474 WX_ANY_DEFINE_SUB_TYPE(float, Double)
475 WX_ANY_DEFINE_SUB_TYPE(double, Double)
476
477
478 //
479 // Defines a dummy wxAnyValueTypeImpl<> with given export
480 // declaration. This is needed if a class is used with
481 // wxAny in both user shared library and application.
482 //
483 #define wxDECLARE_ANY_TYPE(CLS, DECL) \
484 template<> \
485 class DECL wxAnyValueTypeImpl<CLS> : \
486 public wxAnyValueTypeImplBase<CLS> \
487 { \
488 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
489 public: \
490 wxAnyValueTypeImpl() : \
491 wxAnyValueTypeImplBase<CLS>() { } \
492 virtual ~wxAnyValueTypeImpl() { } \
493 \
494 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
495 wxAnyValueType* dstType, \
496 wxAnyValueBuffer& dst) const \
497 { \
498 wxUnusedVar(src); \
499 wxUnusedVar(dstType); \
500 wxUnusedVar(dst); \
501 return false; \
502 } \
503 };
504
505
506 // Make sure some of wx's own types get the right wxAnyValueType export
507 // (this is needed only for types that are referred to from wxBase.
508 // currently we may not use any of these types from there, but let's
509 // use the macro on at least one to make sure it compiles since we can't
510 // really test it properly in unittests since a separate DLL would
511 // be needed).
512 #if wxUSE_DATETIME
513 #include "wx/datetime.h"
514 wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
515 #endif
516
517 //#include "wx/object.h"
518 //wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
519
520 //#include "wx/arrstr.h"
521 //wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
522
523
524 #if wxUSE_VARIANT
525
526 class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
527
528 // Because of header inter-dependencies, cannot include this earlier
529 #include "wx/variant.h"
530
531 //
532 // wxVariantData* data type implementation. For cases when appropriate
533 // wxAny<->wxVariant conversion code is missing.
534 //
535
536 class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
537 public wxAnyValueTypeImplBase<wxVariantData*>
538 {
539 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
540 public:
541 wxAnyValueTypeImplVariantData() :
542 wxAnyValueTypeImplBase<wxVariantData*>() { }
543 virtual ~wxAnyValueTypeImplVariantData() { }
544
545 virtual void DeleteValue(wxAnyValueBuffer& buf) const
546 {
547 wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
548 if ( data )
549 data->DecRef();
550 }
551
552 virtual void CopyBuffer(const wxAnyValueBuffer& src,
553 wxAnyValueBuffer& dst) const
554 {
555 wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
556 if ( data )
557 data->IncRef();
558 dst.m_ptr = data;
559 }
560
561 static void SetValue(wxVariantData* value,
562 wxAnyValueBuffer& buf)
563 {
564 value->IncRef();
565 buf.m_ptr = value;
566 }
567
568 static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
569 {
570 return static_cast<wxVariantData*>(buf.m_ptr);
571 }
572
573 virtual bool ConvertValue(const wxAnyValueBuffer& src,
574 wxAnyValueType* dstType,
575 wxAnyValueBuffer& dst) const
576 {
577 wxUnusedVar(src);
578 wxUnusedVar(dstType);
579 wxUnusedVar(dst);
580 return false;
581 }
582 };
583
584 template<>
585 class wxAnyValueTypeImpl<wxVariantData*> :
586 public wxAnyValueTypeImplVariantData
587 {
588 public:
589 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
590 virtual ~wxAnyValueTypeImpl() { }
591 };
592
593 #endif // wxUSE_VARIANT
594
595 #ifdef __VISUALC6__
596 // Re-enable useless VC6 warnings
597 #pragma warning (pop)
598 #endif
599
600
601 /*
602 Let's define a discrete Null value so we don't have to really
603 ever check if wxAny.m_type pointer is NULL or not. This is an
604 optimization, mostly. Implementation of this value type is
605 "hidden" in the source file.
606 */
607 extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
608
609
610 //
611 // We need to implement custom signed/unsigned int equals operators
612 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
613 #define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
614 bool operator==(TS value) const \
615 { \
616 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
617 return (value == static_cast<TS> \
618 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
619 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
620 return (value == static_cast<TS> \
621 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
622 return false; \
623 } \
624 bool operator==(TUS value) const \
625 { \
626 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
627 return (value == static_cast<TUS> \
628 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
629 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
630 return (value == static_cast<TUS> \
631 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
632 return false; \
633 }
634
635
636 #if wxUSE_VARIANT
637
638 // Note that the following functions are implemented outside wxAny class
639 // so that it can reside entirely in header and lack the export declaration.
640
641 // Helper function used to associate wxAnyValueType with a wxVariantData.
642 extern WXDLLIMPEXP_BASE void
643 wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
644
645 // This function performs main wxAny to wxVariant conversion duties.
646 extern WXDLLIMPEXP_BASE bool
647 wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
648
649 #endif // wxUSE_VARIANT
650
651
652 //
653 // The wxAny class represents a container for any type. A variant's value
654 // can be changed at run time, possibly to a different type of value.
655 //
656 // As standard, wxAny can store value of almost any type, in a fairly
657 // optimal manner even.
658 //
659 class wxAny
660 {
661 public:
662 /**
663 Default constructor.
664 */
665 wxAny()
666 {
667 m_type = wxAnyNullValueType;
668 }
669
670 /**
671 Destructor.
672 */
673 ~wxAny()
674 {
675 m_type->DeleteValue(m_buffer);
676 }
677
678 //@{
679 /**
680 Various constructors.
681 */
682 template<typename T>
683 wxAny(const T& value)
684 {
685 m_type = wxAnyValueTypeImpl<T>::sm_instance;
686 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
687 }
688
689 wxAny(const char* value)
690 {
691 m_type = wxAnyNullValueType;
692 Assign(wxString(value));
693 }
694
695 wxAny(const wchar_t* value)
696 {
697 m_type = wxAnyNullValueType;
698 Assign(wxString(value));
699 }
700
701 wxAny(const wxAny& any)
702 {
703 m_type = wxAnyNullValueType;
704 AssignAny(any);
705 }
706
707 #if wxUSE_VARIANT
708 template<>
709 wxAny(const wxVariant& variant)
710 {
711 m_type = wxAnyNullValueType;
712 AssignVariant(variant);
713 }
714 #endif
715
716 //@}
717
718 /**
719 Use this template function for checking if this wxAny holds
720 a specific C++ data type.
721
722 @remarks This template function does not work on some older compilers
723 (such as Visual C++ 6.0). For full compiler ccompatibility
724 please use wxANY_CHECK_TYPE(any, T) macro instead.
725
726 @see wxAnyValueType::CheckType()
727 */
728 // FIXME-VC6: remove this hack when VC6 is no longer supported
729 template <typename T>
730 bool CheckType(T* = NULL)
731 {
732 return m_type->CheckType<T>();
733 }
734
735 /**
736 Returns the value type as wxAnyValueType instance.
737
738 @remarks You cannot reliably test whether two wxAnys are of
739 same value type by simply comparing return values
740 of wxAny::GetType(). Instead use
741 wxAnyValueType::CheckType<T>() template function.
742 */
743 const wxAnyValueType* GetType() const
744 {
745 return m_type;
746 }
747
748 /**
749 Tests if wxAny is null (that is, whether there is data).
750 */
751 bool IsNull() const
752 {
753 return (m_type == wxAnyNullValueType);
754 }
755
756 /**
757 Makes wxAny null (that is, clears it).
758 */
759 void MakeNull()
760 {
761 m_type->DeleteValue(m_buffer);
762 m_type = wxAnyNullValueType;
763 }
764
765 //@{
766 /**
767 Assignment operators.
768 */
769 wxAny& operator=(const wxAny &any)
770 {
771 if (this != &any)
772 AssignAny(any);
773 return *this;
774 }
775
776 #if wxUSE_VARIANT
777 wxAny& operator=(const wxVariant &variant)
778 {
779 AssignVariant(variant);
780 return *this;
781 }
782 #endif
783
784 template<typename T>
785 wxAny& operator=(const T &value)
786 {
787 m_type->DeleteValue(m_buffer);
788 m_type = wxAnyValueTypeImpl<T>::sm_instance;
789 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
790 return *this;
791 }
792
793 wxAny& operator=(const char* value)
794 { Assign(wxString(value)); return *this; }
795 wxAny& operator=(const wchar_t* value)
796 { Assign(wxString(value)); return *this; }
797 //@}
798
799 //@{
800 /**
801 Equality operators.
802 */
803 bool operator==(const wxString& value) const
804 {
805 if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
806 return false;
807
808 return value ==
809 static_cast<wxString>
810 (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
811 }
812
813 bool operator==(const char* value) const
814 { return (*this) == wxString(value); }
815 bool operator==(const wchar_t* value) const
816 { return (*this) == wxString(value); }
817
818 //
819 // We need to implement custom signed/unsigned int equals operators
820 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
821 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
822 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
823 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
824 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
825 #ifdef wxLongLong_t
826 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
827 #endif
828
829 bool operator==(float value) const
830 {
831 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
832 return false;
833
834 return value ==
835 static_cast<float>
836 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
837 }
838
839 bool operator==(double value) const
840 {
841 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
842 return false;
843
844 return value ==
845 static_cast<double>
846 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
847 }
848
849 bool operator==(bool value) const
850 {
851 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
852 return false;
853
854 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
855 }
856
857 //@}
858
859 //@{
860 /**
861 Inequality operators (implement as template).
862 */
863 template<typename T>
864 bool operator!=(const T& value) const
865 { return !((*this) == value); }
866 //@}
867
868 /**
869 This template function converts wxAny into given type. No dynamic
870 conversion is performed, so if the type is incorrect an assertion
871 failure will occur in debug builds, and a bogus value is returned
872 in release ones.
873
874 @remarks This template function does not work on some older compilers
875 (such as Visual C++ 6.0). For full compiler compatibility
876 please use wxANY_AS(any, T) macro instead.
877 */
878 // FIXME-VC6: remove this hack when VC6 is no longer supported
879 template<typename T>
880 T As(T* = NULL) const
881 {
882 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
883 {
884 wxFAIL_MSG("Incorrect or non-convertible data type");
885 }
886
887 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
888 }
889
890 /**
891 Template function that etrieves and converts the value of this
892 variant to the type that T* value is.
893
894 @return Returns @true if conversion was succesfull.
895 */
896 template<typename T>
897 bool GetAs(T* value) const
898 {
899 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
900 {
901 wxAnyValueType* otherType =
902 wxAnyValueTypeImpl<T>::sm_instance;
903 wxAnyValueBuffer temp_buf;
904
905 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
906 return false;
907
908 *value =
909 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
910 otherType->DeleteValue(temp_buf);
911
912 return true;
913 }
914 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
915 return true;
916 }
917
918 #if wxUSE_VARIANT
919 // GetAs() wxVariant specialization
920 template<>
921 bool GetAs(wxVariant* value) const
922 {
923 return wxConvertAnyToVariant(*this, value);
924 }
925 #endif
926
927 private:
928 // Assignment functions
929 void AssignAny(const wxAny& any)
930 {
931 // Must delete value - CopyBuffer() never does that
932 m_type->DeleteValue(m_buffer);
933
934 wxAnyValueType* newType = any.m_type;
935
936 if ( !newType->IsSameType(m_type) )
937 m_type = newType;
938
939 newType->CopyBuffer(any.m_buffer, m_buffer);
940 }
941
942 #if wxUSE_VARIANT
943 void AssignVariant(const wxVariant& variant)
944 {
945 wxVariantData* data = variant.GetData();
946
947 if ( data && data->GetAsAny(this) )
948 return;
949
950 m_type->DeleteValue(m_buffer);
951
952 if ( variant.IsNull() )
953 {
954 // Init as Null
955 m_type = wxAnyNullValueType;
956 }
957 else
958 {
959 // If everything else fails, wrap the whole wxVariantData
960 m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance;
961 wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
962 }
963 }
964 #endif
965
966 template<typename T>
967 void Assign(const T &value)
968 {
969 m_type->DeleteValue(m_buffer);
970 m_type = wxAnyValueTypeImpl<T>::sm_instance;
971 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
972 }
973
974 // Data
975 wxAnyValueBuffer m_buffer;
976 wxAnyValueType* m_type;
977 };
978
979
980 //
981 // This method of checking the type is compatible with VC6
982 #define wxANY_CHECK_TYPE(any, T) \
983 wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)
984
985
986 //
987 // This method of getting the value is compatible with VC6
988 #define wxANY_AS(any, T) \
989 any.As(static_cast<T*>(NULL))
990
991
992 template<typename T>
993 inline bool wxAnyValueType::CheckType(T* reserved)
994 {
995 wxUnusedVar(reserved);
996 return wxAnyValueTypeImpl<T>::IsSameClass(this);
997 }
998
999
1000
1001 #endif // wxUSE_ANY
1002
1003 #endif // _WX_ANY_H_