]> git.saurik.com Git - wxWidgets.git/blame - include/wx/any.h
Add support for gradient stops to wxGraphicsContext.
[wxWidgets.git] / include / wx / any.h
CommitLineData
39601a7f
VZ
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"
7db064f6 22#include "wx/typeinfo.h"
39601a7f
VZ
23
24
25// Size of the wxAny value buffer.
26enum
27{
28 WX_ANY_VALUE_BUFFER_SIZE = 16
29};
30
31union wxAnyValueBuffer
32{
ca5a3614
JS
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
39601a7f
VZ
43 void* m_ptr;
44 wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
45};
46
39601a7f
VZ
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//
52class WXDLLIMPEXP_BASE wxAnyValueType
53{
7db064f6 54 WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
39601a7f
VZ
55public:
56 /**
57 Default constructor.
58 */
59 wxAnyValueType();
60
61 /**
62 Destructor.
63 */
64 virtual ~wxAnyValueType()
65 {
66 }
67
39601a7f
VZ
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 /**
24985a9b
JS
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.
39601a7f
VZ
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);
114private:
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
39601a7f
VZ
122
123/**
124 Helper macro for defining user value types.
125
7db064f6
JS
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.
39601a7f
VZ
130*/
131#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
132 friend class wxAny; \
7db064f6 133 WX_DECLARE_TYPEINFO_INLINE(CLS) \
39601a7f 134public: \
39601a7f
VZ
135 static bool IsSameClass(const wxAnyValueType* otherType) \
136 { \
7db064f6 137 return wxTypeId(*sm_instance) == wxTypeId(*otherType); \
39601a7f
VZ
138 } \
139 virtual bool IsSameType(const wxAnyValueType* otherType) const \
140 { \
141 return IsSameClass(otherType); \
142 } \
143private: \
144 static CLS* sm_instance; \
145public: \
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*/
165namespace wxPrivate
166{
167
168template<typename T>
169class wxAnyValueTypeOpsMovable
170{
171public:
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 {
1237a25b
JS
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;
39601a7f
VZ
190 }
191};
192
193
194template<typename T>
195class wxAnyValueTypeOpsGeneric
196{
197public:
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*/
243template<typename T>
244class 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
252public:
253 wxAnyValueTypeImplBase() : wxAnyValueType() { }
254 virtual ~wxAnyValueTypeImplBase() { }
255
256 virtual void DeleteValue(wxAnyValueBuffer& buf) const
257 {
258 Ops::DeleteValue(buf);
39601a7f
VZ
259 }
260
261 virtual void CopyBuffer(const wxAnyValueBuffer& src,
262 wxAnyValueBuffer& dst) const
263 {
39601a7f
VZ
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*/
292template<typename T>
293class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
294{
295 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
296public:
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
311template<typename T>
312wxAnyValueTypeImpl<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) \
321template<> \
322class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
323{ \
324 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
325public: \
326 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
327 virtual ~wxAnyValueTypeImpl() { } \
328 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
329 { \
1237a25b
JS
330 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
331 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
332 *dptr = static_cast<UseDataType>(value); \
39601a7f
VZ
333 } \
334 static T GetValue(const wxAnyValueBuffer& buf) \
335 { \
1237a25b
JS
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); \
39601a7f
VZ
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
358class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
359 public wxAnyValueTypeImplBase<wxAnyBaseIntType>
360{
361 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
362public:
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
373class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
374 public wxAnyValueTypeImplBase<wxAnyBaseUintType>
375{
376 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
377public:
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
388WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
389WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
390WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
391WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
392#ifdef wxLongLong_t
393WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
394#endif
395
396WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
397WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
398WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
399WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
400#ifdef wxLongLong_t
401WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
402#endif
403
404
405//
406// String value type
407//
408class WXDLLIMPEXP_BASE wxAnyValueTypeImplString :
409 public wxAnyValueTypeImplBase<wxString>
410{
411 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
412public:
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
427template<>
428class wxAnyValueTypeImpl<wxString> : public wxAnyValueTypeImplString
429{
430public:
431 wxAnyValueTypeImpl() : wxAnyValueTypeImplString() { }
432 virtual ~wxAnyValueTypeImpl() { }
433};
434
435
436//
437// Bool value type
438//
439template<>
440class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
441 public wxAnyValueTypeImplBase<bool>
442{
443 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
444public:
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//
457class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
458 public wxAnyValueTypeImplBase<double>
459{
460 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
461public:
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
472typedef double wxAnyBaseDoubleType;
473
474WX_ANY_DEFINE_SUB_TYPE(float, Double)
475WX_ANY_DEFINE_SUB_TYPE(double, Double)
476
477
c5fe6a5b
JS
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) \
484template<> \
485class DECL wxAnyValueTypeImpl<CLS> : \
486 public wxAnyValueTypeImplBase<CLS> \
487{ \
488 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
489public: \
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
39601a7f
VZ
525#ifdef __VISUALC6__
526 // Re-enable useless VC6 warnings
527 #pragma warning (pop)
528#endif
529
530
531/*
532 Let's define a discrete Null value so we don't have to really
533 ever check if wxAny.m_type pointer is NULL or not. This is an
534 optimization, mostly. Implementation of this value type is
535 "hidden" in the source file.
536*/
537extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
538
539
540//
541// We need to implement custom signed/unsigned int equals operators
542// for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
543#define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
544bool operator==(TS value) const \
545{ \
546 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
547 return (value == static_cast<TS> \
548 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
549 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
550 return (value == static_cast<TS> \
551 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
552 return false; \
553} \
554bool operator==(TUS value) const \
555{ \
556 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
557 return (value == static_cast<TUS> \
558 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
559 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
560 return (value == static_cast<TUS> \
561 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
562 return false; \
563}
564
565
566//
567// The wxAny class represents a container for any type. A variant's value
568// can be changed at run time, possibly to a different type of value.
569//
570// As standard, wxAny can store value of almost any type, in a fairly
571// optimal manner even.
572//
45de347c 573class wxAny
39601a7f
VZ
574{
575public:
576 /**
577 Default constructor.
578 */
579 wxAny()
580 {
581 m_type = wxAnyNullValueType;
582 }
583
584 /**
585 Destructor.
586 */
587 ~wxAny()
588 {
589 m_type->DeleteValue(m_buffer);
590 }
591
592 //@{
593 /**
594 Various constructors.
595 */
596 wxAny(const char* value)
597 {
598 m_type = wxAnyNullValueType;
599 Assign(wxString(value));
600 }
601 wxAny(const wchar_t* value)
602 {
603 m_type = wxAnyNullValueType;
604 Assign(wxString(value));
605 }
606
607 wxAny(const wxAny& any)
608 {
609 m_type = wxAnyNullValueType;
610 AssignAny(any);
611 }
612
613 template<typename T>
614 wxAny(const T& value)
615 {
616 m_type = wxAnyValueTypeImpl<T>::sm_instance;
617 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
618 }
619 //@}
620
621 /**
622 Use this template function for checking if this wxAny holds
623 a specific C++ data type.
624
625 @remarks This template function does not work on some older compilers
626 (such as Visual C++ 6.0). For full compiler ccompatibility
627 please use wxANY_CHECK_TYPE(any, T) macro instead.
628
629 @see wxAnyValueType::CheckType()
630 */
631 // FIXME-VC6: remove this hack when VC6 is no longer supported
632 template <typename T>
633 bool CheckType(T* = NULL)
634 {
635 return m_type->CheckType<T>();
636 }
637
638 /**
639 Returns the value type as wxAnyValueType instance.
640
641 @remarks You cannot reliably test whether two wxAnys are of
642 same value type by simply comparing return values
643 of wxAny::GetType(). Instead use
644 wxAnyValueType::CheckType<T>() template function.
645 */
646 const wxAnyValueType* GetType() const
647 {
648 return m_type;
649 }
650
651 /**
652 Tests if wxAny is null (that is, whether there is data).
653 */
654 bool IsNull() const
655 {
656 return (m_type == wxAnyNullValueType);
657 }
658
659 /**
660 Makes wxAny null (that is, clears it).
661 */
662 void MakeNull()
663 {
664 m_type->DeleteValue(m_buffer);
665 m_type = wxAnyNullValueType;
666 }
667
668 //@{
669 /**
670 Assignment operators.
671 */
672 wxAny& operator=(const wxAny &any)
673 {
2a32b807
PC
674 if (this != &any)
675 AssignAny(any);
39601a7f
VZ
676 return *this;
677 }
678
679 template<typename T>
680 wxAny& operator=(const T &value)
681 {
682 m_type->DeleteValue(m_buffer);
683 m_type = wxAnyValueTypeImpl<T>::sm_instance;
684 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
685 return *this;
686 }
687
688 wxAny& operator=(const char* value)
689 { Assign(wxString(value)); return *this; }
690 wxAny& operator=(const wchar_t* value)
691 { Assign(wxString(value)); return *this; }
692 //@}
693
694 //@{
695 /**
696 Equality operators.
697 */
698 bool operator==(const wxString& value) const
699 {
700 if ( !wxAnyValueTypeImpl<wxString>::IsSameClass(m_type) )
701 return false;
702
703 return value ==
704 static_cast<wxString>
705 (wxAnyValueTypeImpl<wxString>::GetValue(m_buffer));
706 }
707
708 bool operator==(const char* value) const
709 { return (*this) == wxString(value); }
710 bool operator==(const wchar_t* value) const
711 { return (*this) == wxString(value); }
712
713 //
714 // We need to implement custom signed/unsigned int equals operators
715 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
716 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
717 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
718 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
719 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
720#ifdef wxLongLong_t
721 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
722#endif
723
724 bool operator==(float value) const
725 {
726 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
727 return false;
728
729 return value ==
730 static_cast<float>
731 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
732 }
733
734 bool operator==(double value) const
735 {
736 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
737 return false;
738
739 return value ==
740 static_cast<double>
741 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
742 }
743
744 bool operator==(bool value) const
745 {
746 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
747 return false;
748
749 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
750 }
751
752 //@}
753
754 //@{
755 /**
756 Inequality operators (implement as template).
757 */
758 template<typename T>
759 bool operator!=(const T& value) const
760 { return !((*this) == value); }
761 //@}
762
763 /**
764 This template function converts wxAny into given type. No dynamic
765 conversion is performed, so if the type is incorrect an assertion
766 failure will occur in debug builds, and a bogus value is returned
767 in release ones.
768
769 @remarks This template function does not work on some older compilers
770 (such as Visual C++ 6.0). For full compiler ccompatibility
771 please use wxANY_AS(any, T) macro instead.
772 */
773 // FIXME-VC6: remove this hack when VC6 is no longer supported
774 template<typename T>
775 T As(T* = NULL) const
776 {
777 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
01937278 778 {
39601a7f 779 wxFAIL_MSG("Incorrect or non-convertible data type");
01937278
VZ
780 }
781
39601a7f
VZ
782 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
783 }
784
785 /**
786 Template function that etrieves and converts the value of this
787 variant to the type that T* value is.
788
789 @return Returns @true if conversion was succesfull.
790 */
791 template<typename T>
792 bool GetAs(T* value) const
793 {
794 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
795 {
796 wxAnyValueType* otherType =
797 wxAnyValueTypeImpl<T>::sm_instance;
798 wxAnyValueBuffer temp_buf;
799
800 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
801 return false;
802
803 *value =
804 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
805 otherType->DeleteValue(temp_buf);
806
807 return true;
808 }
809 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
810 return true;
811 }
812
813private:
814 // Assignment functions
45de347c
VZ
815 void AssignAny(const wxAny& any)
816 {
24985a9b
JS
817 // Must delete value - CopyBuffer() never does that
818 m_type->DeleteValue(m_buffer);
819
820 wxAnyValueType* newType = any.m_type;
821
822 if ( !newType->IsSameType(m_type) )
823 m_type = newType;
824
825 newType->CopyBuffer(any.m_buffer, m_buffer);
45de347c 826 }
39601a7f
VZ
827
828 template<typename T>
829 void Assign(const T &value)
830 {
831 m_type->DeleteValue(m_buffer);
832 m_type = wxAnyValueTypeImpl<T>::sm_instance;
833 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
834 }
835
836 // Data
39601a7f 837 wxAnyValueBuffer m_buffer;
04110679 838 wxAnyValueType* m_type;
39601a7f
VZ
839};
840
841
842//
843// This method of checking the type is compatible with VC6
844#define wxANY_CHECK_TYPE(any, T) \
845 wxANY_VALUE_TYPE_CHECK_TYPE(any.GetType(), T)
846
847
848//
849// This method of getting the value is compatible with VC6
850#define wxANY_AS(any, T) \
851 any.As(static_cast<T*>(NULL))
852
853
854template<typename T>
855inline bool wxAnyValueType::CheckType(T* reserved)
856{
857 wxUnusedVar(reserved);
858 return wxAnyValueTypeImpl<T>::IsSameClass(this);
859}
860
861
862
863#endif // wxUSE_ANY
864
865#endif // _WX_ANY_H_