]> git.saurik.com Git - wxWidgets.git/blob - include/wx/any.h
b99e84bb99ae987a5caf0d942eb5f576f69cde4c
[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 AssignAny(any);
667 return *this;
668 }
669
670 template<typename T>
671 wxAny& operator=(const T &value)
672 {
673 m_type->DeleteValue(m_buffer);
674 m_type = wxAnyValueTypeImpl<T>::sm_instance;
675 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
676 return *this;
677 }
678
679 wxAny& operator=(const char* value)
680 { Assign(wxString(value)); return *this; }
681 wxAny& operator=(const wchar_t* value)
682 { Assign(wxString(value)); return *this; }
683 //@}
684
685 //@{
686 /**
687 Equality operators.
688 */
689 bool operator==(const wxString& value) const
690 {
691 if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
692 return false;
693
694 return value ==
695 static_cast<wxString>
696 (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
697 }
698
699 bool operator==(const char* value) const
700 { return (*this) == wxString(value); }
701 bool operator==(const wchar_t* value) const
702 { return (*this) == wxString(value); }
703
704 //
705 // We need to implement custom signed/unsigned int equals operators
706 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
707 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
708 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
709 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
710 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
711 #ifdef wxLongLong_t
712 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
713 #endif
714
715 bool operator==(float value) const
716 {
717 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
718 return false;
719
720 return value ==
721 static_cast<float>
722 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
723 }
724
725 bool operator==(double value) const
726 {
727 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
728 return false;
729
730 return value ==
731 static_cast<double>
732 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
733 }
734
735 bool operator==(bool value) const
736 {
737 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
738 return false;
739
740 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
741 }
742
743 //@}
744
745 //@{
746 /**
747 Inequality operators (implement as template).
748 */
749 template<typename T>
750 bool operator!=(const T& value) const
751 { return !((*this) == value); }
752 //@}
753
754 /**
755 This template function converts wxAny into given type. No dynamic
756 conversion is performed, so if the type is incorrect an assertion
757 failure will occur in debug builds, and a bogus value is returned
758 in release ones.
759
760 @remarks This template function does not work on some older compilers
761 (such as Visual C++ 6.0). For full compiler ccompatibility
762 please use wxANY_AS(any, T) macro instead.
763 */
764 // FIXME-VC6: remove this hack when VC6 is no longer supported
765 template<typename T>
766 T As(T* = NULL) const
767 {
768 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
769 {
770 wxFAIL_MSG("Incorrect or non-convertible data type");
771 }
772
773 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
774 }
775
776 /**
777 Template function that etrieves and converts the value of this
778 variant to the type that T* value is.
779
780 @return Returns @true if conversion was succesfull.
781 */
782 template<typename T>
783 bool GetAs(T* value) const
784 {
785 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
786 {
787 wxAnyValueType* otherType =
788 wxAnyValueTypeImpl<T>::sm_instance;
789 wxAnyValueBuffer temp_buf;
790
791 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
792 return false;
793
794 *value =
795 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
796 otherType->DeleteValue(temp_buf);
797
798 return true;
799 }
800 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
801 return true;
802 }
803
804 private:
805 // Assignment functions
806 void AssignAny(const wxAny& any)
807 {
808 // Must delete value - CopyBuffer() never does that
809 m_type->DeleteValue(m_buffer);
810
811 wxAnyValueType* newType = any.m_type;
812
813 if ( !newType->IsSameType(m_type) )
814 m_type = newType;
815
816 newType->CopyBuffer(any.m_buffer, m_buffer);
817 }
818
819 template<typename T>
820 void Assign(const T &value)
821 {
822 m_type->DeleteValue(m_buffer);
823 m_type = wxAnyValueTypeImpl<T>::sm_instance;
824 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
825 }
826
827 // Data
828 wxAnyValueBuffer m_buffer;
829 wxAnyValueType* m_type;
830 };
831
832
833 //
834 // This method of checking the type is compatible with VC6
835 #define wxANY_CHECK_TYPE(any, T) \
836 wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)
837
838
839 //
840 // This method of getting the value is compatible with VC6
841 #define wxANY_AS(any, T) \
842 any.As(static_cast<T*>(NULL))
843
844
845 template<typename T>
846 inline bool wxAnyValueType::CheckType(T* reserved)
847 {
848 wxUnusedVar(reserved);
849 return wxAnyValueTypeImpl<T>::IsSameClass(this);
850 }
851
852
853
854 #endif // wxUSE_ANY
855
856 #endif // _WX_ANY_H_