1
/////////////////////////////////////////////////////////////////////////////
3
// Purpose: wxAny class
4
// Author: Jaakko Salli
7
// RCS-ID: $Id: any.h 66621 2011-01-07 17:22:59Z SC $
8
// Copyright: (c) wxWidgets team
9
// Licence: wxWindows licence
10
/////////////////////////////////////////////////////////////////////////////
19
#include <new> // for placement new
20
#include "wx/string.h"
21
#include "wx/meta/if.h"
22
#include "wx/typeinfo.h"
25
// Size of the wxAny value buffer.
28
WX_ANY_VALUE_BUFFER_SIZE = 16
31
union wxAnyValueBuffer
38
long double m_longDouble;
39
void ( *m_funcPtr )(void);
40
void ( wxAnyValueBuffer::*m_mFuncPtr )(void);
44
wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
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.
52
class WXDLLIMPEXP_BASE wxAnyValueType
54
WX_DECLARE_ABSTRACT_TYPEINFO(wxAnyValueType)
66
virtual ~wxAnyValueType()
71
This function is used for internal type matching.
73
virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
76
This function is called every time the data in wxAny
77
buffer needs to be freed.
79
virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
82
Implement this for buffer-to-buffer copy.
85
This is the source data buffer.
88
This is the destination data buffer that is in either
89
uninitialized or freed state.
91
virtual void CopyBuffer(const wxAnyValueBuffer& src,
92
wxAnyValueBuffer& dst) const = 0;
95
Convert value into buffer of different type. Return false if
98
virtual bool ConvertValue(const wxAnyValueBuffer& src,
99
wxAnyValueType* dstType,
100
wxAnyValueBuffer& dst) const = 0;
103
Use this template function for checking if wxAnyValueType represents
104
a specific C++ data type.
106
@remarks This template function does not work on some older compilers
107
(such as Visual C++ 6.0). For full compiler compatibility
108
please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
111
@see wxAny::CheckType()
113
// FIXME-VC6: remove this hack when VC6 is no longer supported
114
template <typename T>
115
bool CheckType(T* reserved = NULL) const;
117
#if wxUSE_EXTENDED_RTTI
118
virtual const wxTypeInfo* GetTypeInfo() const = 0;
125
// We need to allocate wxAnyValueType instances in heap, and need to use
126
// scoped ptr to properly deallocate them in dynamic library use cases.
127
// Here we have a minimal specialized scoped ptr implementation to deal
128
// with various compiler-specific problems with template class' static
129
// member variable of template type with explicit constructor which
130
// is initialized in global scope.
132
class wxAnyValueTypeScopedPtr
135
wxAnyValueTypeScopedPtr(wxAnyValueType* ptr) : m_ptr(ptr) { }
136
~wxAnyValueTypeScopedPtr() { delete m_ptr; }
137
wxAnyValueType* get() const { return m_ptr; }
139
wxAnyValueType* m_ptr;
144
// This method of checking the type is compatible with VC6
145
#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
146
wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
150
Helper macro for defining user value types.
152
Even though C++ RTTI would be fully available to use, we'd have to to
153
facilitate sub-type system which allows, for instance, wxAny with
154
signed short '15' to be treated equal to wxAny with signed long long '15'.
155
Having sm_instance is important here.
157
NB: We really need to have wxAnyValueType instances allocated
158
in heap. They are stored as static template member variables,
159
and with them we just can't be too careful (eg. not allocating
160
them in heap broke the type identification in GCC).
162
#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
163
friend class wxAny; \
164
WX_DECLARE_TYPEINFO_INLINE(CLS) \
166
static bool IsSameClass(const wxAnyValueType* otherType) \
168
return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
170
virtual bool IsSameType(const wxAnyValueType* otherType) const \
172
return IsSameClass(otherType); \
175
static wxAnyValueTypeScopedPtr sm_instance; \
177
static wxAnyValueType* GetInstance() \
179
return sm_instance.get(); \
183
#define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
184
wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
188
// "non dll-interface class 'xxx' used as base interface
189
#pragma warning (push)
190
#pragma warning (disable:4275)
194
Following are helper classes for the wxAnyValueTypeImplBase.
200
class wxAnyValueTypeOpsInplace
203
static void DeleteValue(wxAnyValueBuffer& buf)
205
T* value = reinterpret_cast<T*>(&buf.m_buffer[0]);
208
// Some compiler may given 'unused variable' warnings without this
212
static void SetValue(const T& value,
213
wxAnyValueBuffer& buf)
216
void* const place = buf.m_buffer;
217
::new(place) T(value);
220
static const T& GetValue(const wxAnyValueBuffer& buf)
222
// Breaking this code into two lines should suppress
223
// GCC's 'type-punned pointer will break strict-aliasing rules'
225
const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
232
class wxAnyValueTypeOpsGeneric
235
template<typename T2>
239
DataHolder(const T2& value)
243
virtual ~DataHolder() { }
247
wxDECLARE_NO_COPY_CLASS(DataHolder);
250
static void DeleteValue(wxAnyValueBuffer& buf)
252
DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
256
static void SetValue(const T& value,
257
wxAnyValueBuffer& buf)
259
DataHolder<T>* holder = new DataHolder<T>(value);
263
static const T& GetValue(const wxAnyValueBuffer& buf)
265
DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
266
return holder->m_value;
270
} // namespace wxPrivate
274
Intermediate template for the generic value type implementation.
275
We can derive from this same value type for multiple actual types
276
(for instance, we can have wxAnyValueTypeImplInt for all signed
277
integer types), and also easily implement specialized templates
278
with specific dynamic type conversion.
281
class wxAnyValueTypeImplBase : public wxAnyValueType
283
typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
284
wxPrivate::wxAnyValueTypeOpsInplace<T>,
285
wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
289
wxAnyValueTypeImplBase() : wxAnyValueType() { }
290
virtual ~wxAnyValueTypeImplBase() { }
292
virtual void DeleteValue(wxAnyValueBuffer& buf) const
294
Ops::DeleteValue(buf);
297
virtual void CopyBuffer(const wxAnyValueBuffer& src,
298
wxAnyValueBuffer& dst) const
300
Ops::SetValue(Ops::GetValue(src), dst);
304
It is important to reimplement this in any specialized template
305
classes that inherit from wxAnyValueTypeImplBase.
307
static void SetValue(const T& value,
308
wxAnyValueBuffer& buf)
310
Ops::SetValue(value, buf);
314
It is important to reimplement this in any specialized template
315
classes that inherit from wxAnyValueTypeImplBase.
317
static const T& GetValue(const wxAnyValueBuffer& buf)
319
return Ops::GetValue(buf);
321
#if wxUSE_EXTENDED_RTTI
322
virtual const wxTypeInfo* GetTypeInfo() const
324
return wxGetTypeInfo((T*)NULL);
331
Generic value type template. Note that bulk of the implementation
332
resides in wxAnyValueTypeImplBase.
335
class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
337
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
339
wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
340
virtual ~wxAnyValueTypeImpl() { }
342
virtual bool ConvertValue(const wxAnyValueBuffer& src,
343
wxAnyValueType* dstType,
344
wxAnyValueBuffer& dst) const
347
wxUnusedVar(dstType);
354
wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>();
358
// Helper macro for using same base value type implementation for multiple
359
// actual C++ data types.
361
#define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
363
class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
365
typedef wxAnyBase##CLSTYPE##Type UseDataType; \
367
wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
368
virtual ~wxAnyValueTypeImpl() { } \
369
static void SetValue(const T& value, wxAnyValueBuffer& buf) \
371
void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
372
UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
373
*dptr = static_cast<UseDataType>(value); \
375
static T GetValue(const wxAnyValueBuffer& buf) \
377
const void* voidPtr = \
378
reinterpret_cast<const void*>(&buf.m_buffer[0]); \
379
const UseDataType* sptr = \
380
reinterpret_cast<const UseDataType*>(voidPtr); \
381
return static_cast<T>(*sptr); \
384
#if wxUSE_EXTENDED_RTTI
385
#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
386
_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
387
virtual const wxTypeInfo* GetTypeInfo() const \
389
return wxGetTypeInfo((T*)NULL); \
393
#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
394
_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
399
// Integer value types
403
typedef wxLongLong_t wxAnyBaseIntType;
404
typedef wxULongLong_t wxAnyBaseUintType;
406
typedef long wxAnyBaseIntType;
407
typedef unsigned long wxAnyBaseUintType;
411
class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
412
public wxAnyValueTypeImplBase<wxAnyBaseIntType>
414
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
416
wxAnyValueTypeImplInt() :
417
wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
418
virtual ~wxAnyValueTypeImplInt() { }
420
virtual bool ConvertValue(const wxAnyValueBuffer& src,
421
wxAnyValueType* dstType,
422
wxAnyValueBuffer& dst) const;
426
class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
427
public wxAnyValueTypeImplBase<wxAnyBaseUintType>
429
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
431
wxAnyValueTypeImplUint() :
432
wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
433
virtual ~wxAnyValueTypeImplUint() { }
435
virtual bool ConvertValue(const wxAnyValueBuffer& src,
436
wxAnyValueType* dstType,
437
wxAnyValueBuffer& dst) const;
441
WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
442
WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
443
WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
444
WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
446
WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
449
WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
450
WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
451
WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
452
WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
454
WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
459
// This macro is used in header, but then in source file we must have:
460
// WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
462
#define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
463
class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
464
public wxAnyValueTypeImplBase<T> \
466
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
468
wxAnyValueTypeImpl##TYPENAME() : \
469
wxAnyValueTypeImplBase<T>() { } \
470
virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
471
virtual bool ConvertValue(const wxAnyValueBuffer& src, \
472
wxAnyValueType* dstType, \
473
wxAnyValueBuffer& dst) const \
475
GV value = GetValue(src); \
476
return CONVFUNC(value, dstType, dst); \
480
class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
483
wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
484
virtual ~wxAnyValueTypeImpl() { } \
487
#define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
488
_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
490
#define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
491
_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
492
CONVFUNC, const T&) \
498
// Convert wxString to destination wxAny value type
499
extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value,
500
wxAnyValueType* dstType,
501
wxAnyValueBuffer& dst);
503
WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString)
504
WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr,
505
wxAnyConvertString, wxString)
506
WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr,
507
wxAnyConvertString, wxString)
513
class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
514
public wxAnyValueTypeImplBase<bool>
516
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
518
wxAnyValueTypeImpl() :
519
wxAnyValueTypeImplBase<bool>() { }
520
virtual ~wxAnyValueTypeImpl() { }
522
virtual bool ConvertValue(const wxAnyValueBuffer& src,
523
wxAnyValueType* dstType,
524
wxAnyValueBuffer& dst) const;
528
// Floating point value type
530
class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
531
public wxAnyValueTypeImplBase<double>
533
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
535
wxAnyValueTypeImplDouble() :
536
wxAnyValueTypeImplBase<double>() { }
537
virtual ~wxAnyValueTypeImplDouble() { }
539
virtual bool ConvertValue(const wxAnyValueBuffer& src,
540
wxAnyValueType* dstType,
541
wxAnyValueBuffer& dst) const;
544
// WX_ANY_DEFINE_SUB_TYPE requires this
545
typedef double wxAnyBaseDoubleType;
547
WX_ANY_DEFINE_SUB_TYPE(float, Double)
548
WX_ANY_DEFINE_SUB_TYPE(double, Double)
552
// Defines a dummy wxAnyValueTypeImpl<> with given export
553
// declaration. This is needed if a class is used with
554
// wxAny in both user shared library and application.
556
#define wxDECLARE_ANY_TYPE(CLS, DECL) \
558
class DECL wxAnyValueTypeImpl<CLS> : \
559
public wxAnyValueTypeImplBase<CLS> \
561
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
563
wxAnyValueTypeImpl() : \
564
wxAnyValueTypeImplBase<CLS>() { } \
565
virtual ~wxAnyValueTypeImpl() { } \
567
virtual bool ConvertValue(const wxAnyValueBuffer& src, \
568
wxAnyValueType* dstType, \
569
wxAnyValueBuffer& dst) const \
572
wxUnusedVar(dstType); \
579
// Make sure some of wx's own types get the right wxAnyValueType export
580
// (this is needed only for types that are referred to from wxBase.
581
// currently we may not use any of these types from there, but let's
582
// use the macro on at least one to make sure it compiles since we can't
583
// really test it properly in unit tests since a separate DLL would
586
#include "wx/datetime.h"
587
wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
590
//#include "wx/object.h"
591
//wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
593
//#include "wx/arrstr.h"
594
//wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
599
class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
601
// Because of header inter-dependencies, cannot include this earlier
602
#include "wx/variant.h"
605
// wxVariantData* data type implementation. For cases when appropriate
606
// wxAny<->wxVariant conversion code is missing.
609
class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
610
public wxAnyValueTypeImplBase<wxVariantData*>
612
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
614
wxAnyValueTypeImplVariantData() :
615
wxAnyValueTypeImplBase<wxVariantData*>() { }
616
virtual ~wxAnyValueTypeImplVariantData() { }
618
virtual void DeleteValue(wxAnyValueBuffer& buf) const
620
wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
625
virtual void CopyBuffer(const wxAnyValueBuffer& src,
626
wxAnyValueBuffer& dst) const
628
wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
634
static void SetValue(wxVariantData* value,
635
wxAnyValueBuffer& buf)
641
static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
643
return static_cast<wxVariantData*>(buf.m_ptr);
646
virtual bool ConvertValue(const wxAnyValueBuffer& src,
647
wxAnyValueType* dstType,
648
wxAnyValueBuffer& dst) const
651
wxUnusedVar(dstType);
658
class wxAnyValueTypeImpl<wxVariantData*> :
659
public wxAnyValueTypeImplVariantData
662
wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
663
virtual ~wxAnyValueTypeImpl() { }
666
#endif // wxUSE_VARIANT
669
// Re-enable useless VC6 warnings
670
#pragma warning (pop)
675
Let's define a discrete Null value so we don't have to really
676
ever check if wxAny.m_type pointer is NULL or not. This is an
677
optimization, mostly. Implementation of this value type is
678
"hidden" in the source file.
680
extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
684
// We need to implement custom signed/unsigned int equals operators
685
// for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
686
#define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
687
bool operator==(TS value) const \
689
if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
690
return (value == static_cast<TS> \
691
(wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
692
if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
693
return (value == static_cast<TS> \
694
(wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
697
bool operator==(TUS value) const \
699
if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
700
return (value == static_cast<TUS> \
701
(wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
702
if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
703
return (value == static_cast<TUS> \
704
(wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
711
// Note that the following functions are implemented outside wxAny class
712
// so that it can reside entirely in header and lack the export declaration.
714
// Helper function used to associate wxAnyValueType with a wxVariantData.
715
extern WXDLLIMPEXP_BASE void
716
wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
718
// This function performs main wxAny to wxVariant conversion duties.
719
extern WXDLLIMPEXP_BASE bool
720
wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
722
#endif // wxUSE_VARIANT
726
// The wxAny class represents a container for any type. A variant's value
727
// can be changed at run time, possibly to a different type of value.
729
// As standard, wxAny can store value of almost any type, in a fairly
730
// optimal manner even.
740
m_type = wxAnyNullValueType;
748
m_type->DeleteValue(m_buffer);
753
Various constructors.
756
wxAny(const T& value)
758
m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
759
wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
762
// These two constructors are needed to deal with string literals
763
wxAny(const char* value)
765
m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get();
766
wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
768
wxAny(const wchar_t* value)
770
m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get();
771
wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
774
wxAny(const wxAny& any)
776
m_type = wxAnyNullValueType;
781
wxAny(const wxVariant& variant)
783
m_type = wxAnyNullValueType;
784
AssignVariant(variant);
791
Use this template function for checking if this wxAny holds
792
a specific C++ data type.
794
@remarks This template function does not work on some older compilers
795
(such as Visual C++ 6.0). For full compiler ccompatibility
796
please use wxANY_CHECK_TYPE(any, T) macro instead.
798
@see wxAnyValueType::CheckType()
800
// FIXME-VC6: remove this hack when VC6 is no longer supported
801
template <typename T>
802
bool CheckType(T* = NULL) const
804
return m_type->CheckType<T>();
808
Returns the value type as wxAnyValueType instance.
810
@remarks You cannot reliably test whether two wxAnys are of
811
same value type by simply comparing return values
812
of wxAny::GetType(). Instead, use wxAny::HasSameType().
816
const wxAnyValueType* GetType() const
822
Returns @true if this and another wxAny have the same
825
bool HasSameType(const wxAny& other) const
827
return GetType()->IsSameType(other.GetType());
831
Tests if wxAny is null (that is, whether there is no data).
835
return (m_type == wxAnyNullValueType);
839
Makes wxAny null (that is, clears it).
843
m_type->DeleteValue(m_buffer);
844
m_type = wxAnyNullValueType;
849
Assignment operators.
852
wxAny& operator=(const T &value)
854
m_type->DeleteValue(m_buffer);
855
m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
856
wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
860
wxAny& operator=(const wxAny &any)
868
wxAny& operator=(const wxVariant &variant)
870
AssignVariant(variant);
875
// These two operators are needed to deal with string literals
876
wxAny& operator=(const char* value)
881
wxAny& operator=(const wchar_t* value)
891
bool operator==(const wxString& value) const
894
if ( !GetAs(&value2) )
896
return value == value2;
899
bool operator==(const char* value) const
900
{ return (*this) == wxString(value); }
901
bool operator==(const wchar_t* value) const
902
{ return (*this) == wxString(value); }
905
// We need to implement custom signed/unsigned int equals operators
906
// for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
907
WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
908
WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
909
WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
910
WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
912
WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
915
bool operator==(float value) const
917
if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
922
(wxAnyValueTypeImpl<float>::GetValue(m_buffer));
925
bool operator==(double value) const
927
if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
932
(wxAnyValueTypeImpl<double>::GetValue(m_buffer));
935
bool operator==(bool value) const
937
if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
940
return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
947
Inequality operators (implement as template).
950
bool operator!=(const T& value) const
951
{ return !((*this) == value); }
955
This template function converts wxAny into given type. In most cases
956
no type conversion is performed, so if the type is incorrect an
957
assertion failure will occur.
959
@remarks For convenience, conversion is done when T is wxString. This
960
is useful when a string literal (which are treated as
961
const char* and const wchar_t*) has been assigned to wxAny.
963
This template function may not work properly with Visual C++
964
6. For full compiler compatibility, please use
965
wxANY_AS(any, T) macro instead.
967
// FIXME-VC6: remove this hack when VC6 is no longer supported
969
T As(T* = NULL) const
971
if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
973
wxFAIL_MSG("Incorrect or non-convertible data type");
976
return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
979
// Allow easy conversion from 'const char *' etc. to wxString
980
// FIXME-VC6: remove this hack when VC6 is no longer supported
982
wxString As(wxString*) const
985
if ( !GetAs(&value) )
987
wxFAIL_MSG("Incorrect or non-convertible data type");
992
#if wxUSE_EXTENDED_RTTI
993
const wxTypeInfo* GetTypeInfo() const
995
return m_type->GetTypeInfo();
999
Template function that retrieves and converts the value of this
1000
variant to the type that T* value is.
1002
@return Returns @true if conversion was successful.
1004
template<typename T>
1005
bool GetAs(T* value) const
1007
if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
1009
wxAnyValueType* otherType =
1010
wxAnyValueTypeImpl<T>::sm_instance.get();
1011
wxAnyValueBuffer temp_buf;
1013
if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
1017
static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
1018
otherType->DeleteValue(temp_buf);
1022
*value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
1027
// GetAs() wxVariant specialization
1028
bool GetAs(wxVariant* value) const
1030
return wxConvertAnyToVariant(*this, value);
1035
// Assignment functions
1036
void AssignAny(const wxAny& any)
1038
// Must delete value - CopyBuffer() never does that
1039
m_type->DeleteValue(m_buffer);
1041
wxAnyValueType* newType = any.m_type;
1043
if ( !newType->IsSameType(m_type) )
1046
newType->CopyBuffer(any.m_buffer, m_buffer);
1050
void AssignVariant(const wxVariant& variant)
1052
wxVariantData* data = variant.GetData();
1054
if ( data && data->GetAsAny(this) )
1057
m_type->DeleteValue(m_buffer);
1059
if ( variant.IsNull() )
1062
m_type = wxAnyNullValueType;
1066
// If everything else fails, wrap the whole wxVariantData
1067
m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get();
1068
wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
1073
template<typename T>
1074
void Assign(const T &value)
1076
m_type->DeleteValue(m_buffer);
1077
m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
1078
wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
1082
wxAnyValueBuffer m_buffer;
1083
wxAnyValueType* m_type;
1088
// This method of checking the type is compatible with VC6
1089
#define wxANY_CHECK_TYPE(any, T) \
1090
wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
1094
// This method of getting the value is compatible with VC6
1095
#define wxANY_AS(any, T) \
1096
(any).As(static_cast<T*>(NULL))
1099
template<typename T>
1100
inline bool wxAnyValueType::CheckType(T* reserved) const
1102
wxUnusedVar(reserved);
1103
return wxAnyValueTypeImpl<T>::IsSameClass(this);
1106
WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE);
1110
#endif // _WX_ANY_H_