]> git.saurik.com Git - wxWidgets.git/blame - include/wx/any.h
Applied #11755: wxBitmapToggleButton Xml Handler
[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 */
0cc226ad
JS
59 wxAnyValueType()
60 {
61 }
39601a7f
VZ
62
63 /**
64 Destructor.
65 */
66 virtual ~wxAnyValueType()
67 {
68 }
69
39601a7f
VZ
70 /**
71 This function is used for internal type matching.
72 */
73 virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
74
75 /**
76 This function is called every time the data in wxAny
77 buffer needs to be freed.
78 */
79 virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
80
81 /**
24985a9b
JS
82 Implement this for buffer-to-buffer copy.
83
84 @param src
85 This is the source data buffer.
86
87 @param dst
88 This is the destination data buffer that is in either
89 uninitialized or freed state.
39601a7f
VZ
90 */
91 virtual void CopyBuffer(const wxAnyValueBuffer& src,
92 wxAnyValueBuffer& dst) const = 0;
93
94 /**
95 Convert value into buffer of different type. Return false if
96 not possible.
97 */
98 virtual bool ConvertValue(const wxAnyValueBuffer& src,
99 wxAnyValueType* dstType,
100 wxAnyValueBuffer& dst) const = 0;
101
102 /**
103 Use this template function for checking if wxAnyValueType represents
104 a specific C++ data type.
105
106 @remarks This template function does not work on some older compilers
107 (such as Visual C++ 6.0). For full compiler ccompatibility
108 please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
109 instead.
110
111 @see wxAny::CheckType()
112 */
113 // FIXME-VC6: remove this hack when VC6 is no longer supported
114 template <typename T>
115 bool CheckType(T* reserved = NULL);
116private:
117};
118
0cc226ad
JS
119
120//
121// We need to allocate wxAnyValueType instances in heap, and need to use
122// scoped ptr to properly deallocate them in dynamic library use cases.
123// Here we have a minimal specialized scoped ptr implementation to deal
124// with various compiler-specific problems with template class' static
125// member variable of template type with explicit constructor which
126// is initialized in global scope.
127//
128class wxAnyValueTypeScopedPtr
129{
130public:
131 wxAnyValueTypeScopedPtr(wxAnyValueType* ptr) : m_ptr(ptr) { }
132 ~wxAnyValueTypeScopedPtr() { delete m_ptr; }
133 wxAnyValueType* get() const { return m_ptr; }
134private:
135 wxAnyValueType* m_ptr;
136};
137
138
39601a7f
VZ
139//
140// This method of checking the type is compatible with VC6
141#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) \
142 wxAnyValueTypeImpl<T>::IsSameClass(valueTypePtr)
143
39601a7f
VZ
144
145/**
146 Helper macro for defining user value types.
147
7db064f6
JS
148 Even though C++ RTTI would be fully available to use, we'd have to to
149 facilitate sub-type system which allows, for instance, wxAny with
150 signed short '15' to be treated equal to wxAny with signed long long '15'.
151 Having sm_instance is important here.
0cc226ad
JS
152
153 NB: We really need to have wxAnyValueType instances allocated
154 in heap. They are stored as static template member variables,
155 and with them we just can't be too careful (eg. not allocating
156 them in heap broke the type identification in GCC).
39601a7f
VZ
157*/
158#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
159 friend class wxAny; \
7db064f6 160 WX_DECLARE_TYPEINFO_INLINE(CLS) \
39601a7f 161public: \
39601a7f
VZ
162 static bool IsSameClass(const wxAnyValueType* otherType) \
163 { \
0cc226ad 164 return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
39601a7f
VZ
165 } \
166 virtual bool IsSameType(const wxAnyValueType* otherType) const \
167 { \
168 return IsSameClass(otherType); \
169 } \
170private: \
0cc226ad 171 static wxAnyValueTypeScopedPtr sm_instance; \
39601a7f
VZ
172public: \
173 static wxAnyValueType* GetInstance() \
174 { \
0cc226ad 175 return sm_instance.get(); \
39601a7f
VZ
176 }
177
178
179#define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
0cc226ad 180wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
39601a7f
VZ
181
182
183#ifdef __VISUALC6__
184 // "non dll-interface class 'xxx' used as base interface
185 #pragma warning (push)
186 #pragma warning (disable:4275)
187#endif
188
189/**
190 Following are helper classes for the wxAnyValueTypeImplBase.
191*/
192namespace wxPrivate
193{
194
195template<typename T>
196class wxAnyValueTypeOpsMovable
197{
198public:
199 static void DeleteValue(wxAnyValueBuffer& buf)
200 {
201 wxUnusedVar(buf);
202 }
203
204 static void SetValue(const T& value,
205 wxAnyValueBuffer& buf)
206 {
207 memcpy(buf.m_buffer, &value, sizeof(T));
208 }
209
210 static const T& GetValue(const wxAnyValueBuffer& buf)
211 {
1237a25b
JS
212 // Breaking this code into two lines should supress
213 // GCC's 'type-punned pointer will break strict-aliasing rules'
214 // warning.
215 const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
216 return *value;
39601a7f
VZ
217 }
218};
219
220
221template<typename T>
222class wxAnyValueTypeOpsGeneric
223{
224public:
225 template<typename T2>
226 class DataHolder
227 {
228 public:
229 DataHolder(const T2& value)
230 {
231 m_value = value;
232 }
233 virtual ~DataHolder() { }
234
235 T2 m_value;
236 private:
237 wxDECLARE_NO_COPY_CLASS(DataHolder);
238 };
239
240 static void DeleteValue(wxAnyValueBuffer& buf)
241 {
242 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
243 delete holder;
244 }
245
246 static void SetValue(const T& value,
247 wxAnyValueBuffer& buf)
248 {
249 DataHolder<T>* holder = new DataHolder<T>(value);
250 buf.m_ptr = holder;
251 }
252
253 static const T& GetValue(const wxAnyValueBuffer& buf)
254 {
255 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
256 return holder->m_value;
257 }
258};
259
260} // namespace wxPrivate
261
262
263/**
264 Intermediate template for the generic value type implementation.
265 We can derive from this same value type for multiple actual types
266 (for instance, we can have wxAnyValueTypeImplInt for all signed
267 integer types), and also easily implement specialized templates
268 with specific dynamic type conversion.
269*/
270template<typename T>
271class wxAnyValueTypeImplBase : public wxAnyValueType
272{
273 typedef typename wxIf< wxIsMovable<T>::value &&
274 sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
275 wxPrivate::wxAnyValueTypeOpsMovable<T>,
276 wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
277 Ops;
278
279public:
280 wxAnyValueTypeImplBase() : wxAnyValueType() { }
281 virtual ~wxAnyValueTypeImplBase() { }
282
283 virtual void DeleteValue(wxAnyValueBuffer& buf) const
284 {
285 Ops::DeleteValue(buf);
39601a7f
VZ
286 }
287
288 virtual void CopyBuffer(const wxAnyValueBuffer& src,
289 wxAnyValueBuffer& dst) const
290 {
39601a7f
VZ
291 Ops::SetValue(Ops::GetValue(src), dst);
292 }
293
294 /**
295 It is important to reimplement this in any specialized template
296 classes that inherit from wxAnyValueTypeImplBase.
297 */
298 static void SetValue(const T& value,
299 wxAnyValueBuffer& buf)
300 {
301 Ops::SetValue(value, buf);
302 }
303
304 /**
305 It is important to reimplement this in any specialized template
306 classes that inherit from wxAnyValueTypeImplBase.
307 */
308 static const T& GetValue(const wxAnyValueBuffer& buf)
309 {
310 return Ops::GetValue(buf);
311 }
312};
313
314
315/*
316 Generic value type template. Note that bulk of the implementation
317 resides in wxAnyValueTypeImplBase.
318*/
319template<typename T>
320class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
321{
322 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
323public:
324 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
325 virtual ~wxAnyValueTypeImpl() { }
326
327 virtual bool ConvertValue(const wxAnyValueBuffer& src,
328 wxAnyValueType* dstType,
329 wxAnyValueBuffer& dst) const
330 {
331 wxUnusedVar(src);
332 wxUnusedVar(dstType);
333 wxUnusedVar(dst);
334 return false;
335 }
336};
337
338template<typename T>
0cc226ad 339wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>();
39601a7f
VZ
340
341
342//
343// Helper macro for using same base value type implementation for multiple
344// actual C++ data types.
345//
346#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
347template<> \
348class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
349{ \
350 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
351public: \
352 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
353 virtual ~wxAnyValueTypeImpl() { } \
354 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
355 { \
1237a25b
JS
356 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
357 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
358 *dptr = static_cast<UseDataType>(value); \
39601a7f
VZ
359 } \
360 static T GetValue(const wxAnyValueBuffer& buf) \
361 { \
1237a25b
JS
362 const void* voidPtr = \
363 reinterpret_cast<const void*>(&buf.m_buffer[0]); \
364 const UseDataType* sptr = \
365 reinterpret_cast<const UseDataType*>(voidPtr); \
366 return static_cast<T>(*sptr); \
39601a7f
VZ
367 } \
368};
369
370
371//
372// Integer value types
373//
374
375#ifdef wxLongLong_t
376 typedef wxLongLong_t wxAnyBaseIntType;
377 typedef wxULongLong_t wxAnyBaseUintType;
378#else
379 typedef long wxAnyBaseIntType;
380 typedef unsigned long wxAnyBaseUintType;
381#endif
382
383
384class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
385 public wxAnyValueTypeImplBase<wxAnyBaseIntType>
386{
387 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
388public:
389 wxAnyValueTypeImplInt() :
390 wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
391 virtual ~wxAnyValueTypeImplInt() { }
392
393 virtual bool ConvertValue(const wxAnyValueBuffer& src,
394 wxAnyValueType* dstType,
395 wxAnyValueBuffer& dst) const;
396};
397
398
399class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
400 public wxAnyValueTypeImplBase<wxAnyBaseUintType>
401{
402 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
403public:
404 wxAnyValueTypeImplUint() :
405 wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
406 virtual ~wxAnyValueTypeImplUint() { }
407
408 virtual bool ConvertValue(const wxAnyValueBuffer& src,
409 wxAnyValueType* dstType,
410 wxAnyValueBuffer& dst) const;
411};
412
413
414WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
415WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
416WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
417WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
418#ifdef wxLongLong_t
419WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
420#endif
421
422WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
423WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
424WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
425WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
426#ifdef wxLongLong_t
427WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
428#endif
429
430
431//
153107b4
JS
432// This macro is used in header, but then in source file we must have:
433// WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
39601a7f 434//
153107b4
JS
435#define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
436class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
437 public wxAnyValueTypeImplBase<T> \
438{ \
439 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
440public: \
441 wxAnyValueTypeImpl##TYPENAME() : \
442 wxAnyValueTypeImplBase<T>() { } \
443 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
444 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
445 wxAnyValueType* dstType, \
446 wxAnyValueBuffer& dst) const \
447 { \
448 GV value = GetValue(src); \
449 return CONVFUNC(value, dstType, dst); \
450 } \
451}; \
452template<> \
453class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
454{ \
455public: \
456 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
457 virtual ~wxAnyValueTypeImpl() { } \
458};
39601a7f 459
153107b4
JS
460#define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
461_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
39601a7f 462
153107b4
JS
463#define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
464_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
465 CONVFUNC, const T&) \
39601a7f 466
153107b4
JS
467//
468// String value type
469//
39601a7f 470
153107b4
JS
471// Convert wxString to destination wxAny value type
472extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value,
473 wxAnyValueType* dstType,
474 wxAnyValueBuffer& dst);
475
476WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString)
477WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr,
478 wxAnyConvertString, wxString)
479WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr,
480 wxAnyConvertString, wxString)
39601a7f
VZ
481
482//
483// Bool value type
484//
485template<>
486class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
487 public wxAnyValueTypeImplBase<bool>
488{
489 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
490public:
491 wxAnyValueTypeImpl() :
492 wxAnyValueTypeImplBase<bool>() { }
493 virtual ~wxAnyValueTypeImpl() { }
494
495 virtual bool ConvertValue(const wxAnyValueBuffer& src,
496 wxAnyValueType* dstType,
497 wxAnyValueBuffer& dst) const;
498};
499
500//
501// Floating point value type
502//
503class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
504 public wxAnyValueTypeImplBase<double>
505{
506 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
507public:
508 wxAnyValueTypeImplDouble() :
509 wxAnyValueTypeImplBase<double>() { }
510 virtual ~wxAnyValueTypeImplDouble() { }
511
512 virtual bool ConvertValue(const wxAnyValueBuffer& src,
513 wxAnyValueType* dstType,
514 wxAnyValueBuffer& dst) const;
515};
516
517// WX_ANY_DEFINE_SUB_TYPE requires this
518typedef double wxAnyBaseDoubleType;
519
520WX_ANY_DEFINE_SUB_TYPE(float, Double)
521WX_ANY_DEFINE_SUB_TYPE(double, Double)
522
523
c5fe6a5b
JS
524//
525// Defines a dummy wxAnyValueTypeImpl<> with given export
526// declaration. This is needed if a class is used with
527// wxAny in both user shared library and application.
528//
529#define wxDECLARE_ANY_TYPE(CLS, DECL) \
530template<> \
531class DECL wxAnyValueTypeImpl<CLS> : \
532 public wxAnyValueTypeImplBase<CLS> \
533{ \
534 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
535public: \
536 wxAnyValueTypeImpl() : \
537 wxAnyValueTypeImplBase<CLS>() { } \
538 virtual ~wxAnyValueTypeImpl() { } \
539 \
540 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
541 wxAnyValueType* dstType, \
542 wxAnyValueBuffer& dst) const \
543 { \
544 wxUnusedVar(src); \
545 wxUnusedVar(dstType); \
546 wxUnusedVar(dst); \
547 return false; \
548 } \
549};
550
551
552// Make sure some of wx's own types get the right wxAnyValueType export
553// (this is needed only for types that are referred to from wxBase.
554// currently we may not use any of these types from there, but let's
555// use the macro on at least one to make sure it compiles since we can't
556// really test it properly in unittests since a separate DLL would
557// be needed).
558#if wxUSE_DATETIME
559 #include "wx/datetime.h"
560 wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
561#endif
562
563//#include "wx/object.h"
564//wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
565
566//#include "wx/arrstr.h"
567//wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
568
569
0bf14ab8
JS
570#if wxUSE_VARIANT
571
572class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
573
574// Because of header inter-dependencies, cannot include this earlier
575#include "wx/variant.h"
576
577//
578// wxVariantData* data type implementation. For cases when appropriate
579// wxAny<->wxVariant conversion code is missing.
580//
581
582class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
583 public wxAnyValueTypeImplBase<wxVariantData*>
584{
585 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
586public:
587 wxAnyValueTypeImplVariantData() :
588 wxAnyValueTypeImplBase<wxVariantData*>() { }
589 virtual ~wxAnyValueTypeImplVariantData() { }
590
591 virtual void DeleteValue(wxAnyValueBuffer& buf) const
592 {
593 wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
594 if ( data )
595 data->DecRef();
596 }
597
598 virtual void CopyBuffer(const wxAnyValueBuffer& src,
599 wxAnyValueBuffer& dst) const
600 {
601 wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
602 if ( data )
603 data->IncRef();
604 dst.m_ptr = data;
605 }
606
607 static void SetValue(wxVariantData* value,
608 wxAnyValueBuffer& buf)
609 {
610 value->IncRef();
611 buf.m_ptr = value;
612 }
613
614 static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
615 {
616 return static_cast<wxVariantData*>(buf.m_ptr);
617 }
618
619 virtual bool ConvertValue(const wxAnyValueBuffer& src,
620 wxAnyValueType* dstType,
621 wxAnyValueBuffer& dst) const
622 {
623 wxUnusedVar(src);
624 wxUnusedVar(dstType);
625 wxUnusedVar(dst);
626 return false;
627 }
628};
629
630template<>
631class wxAnyValueTypeImpl<wxVariantData*> :
632 public wxAnyValueTypeImplVariantData
633{
634public:
635 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
636 virtual ~wxAnyValueTypeImpl() { }
637};
638
639#endif // wxUSE_VARIANT
c5fe6a5b 640
39601a7f
VZ
641#ifdef __VISUALC6__
642 // Re-enable useless VC6 warnings
643 #pragma warning (pop)
644#endif
645
646
647/*
648 Let's define a discrete Null value so we don't have to really
649 ever check if wxAny.m_type pointer is NULL or not. This is an
650 optimization, mostly. Implementation of this value type is
651 "hidden" in the source file.
652*/
653extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
654
655
656//
657// We need to implement custom signed/unsigned int equals operators
658// for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
659#define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
660bool operator==(TS value) const \
661{ \
662 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
663 return (value == static_cast<TS> \
664 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
665 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
666 return (value == static_cast<TS> \
667 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
668 return false; \
669} \
670bool operator==(TUS value) const \
671{ \
672 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
673 return (value == static_cast<TUS> \
674 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
675 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
676 return (value == static_cast<TUS> \
677 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
678 return false; \
679}
680
681
0bf14ab8
JS
682#if wxUSE_VARIANT
683
684// Note that the following functions are implemented outside wxAny class
685// so that it can reside entirely in header and lack the export declaration.
686
687// Helper function used to associate wxAnyValueType with a wxVariantData.
688extern WXDLLIMPEXP_BASE void
689wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
690
691// This function performs main wxAny to wxVariant conversion duties.
692extern WXDLLIMPEXP_BASE bool
693wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
694
695#endif // wxUSE_VARIANT
696
697
39601a7f
VZ
698//
699// The wxAny class represents a container for any type. A variant's value
700// can be changed at run time, possibly to a different type of value.
701//
702// As standard, wxAny can store value of almost any type, in a fairly
703// optimal manner even.
704//
45de347c 705class wxAny
39601a7f
VZ
706{
707public:
708 /**
709 Default constructor.
710 */
711 wxAny()
712 {
713 m_type = wxAnyNullValueType;
714 }
715
716 /**
717 Destructor.
718 */
719 ~wxAny()
720 {
721 m_type->DeleteValue(m_buffer);
722 }
723
724 //@{
725 /**
726 Various constructors.
727 */
ea412ac4
JS
728 template<typename T>
729 wxAny(const T& value)
730 {
0cc226ad 731 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
ea412ac4
JS
732 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
733 }
734
153107b4 735 // These two constructors are needed to deal with string literals
39601a7f
VZ
736 wxAny(const char* value)
737 {
0cc226ad 738 m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get();
153107b4 739 wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
39601a7f
VZ
740 }
741 wxAny(const wchar_t* value)
742 {
0cc226ad 743 m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get();
153107b4 744 wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
39601a7f
VZ
745 }
746
747 wxAny(const wxAny& any)
748 {
749 m_type = wxAnyNullValueType;
750 AssignAny(any);
751 }
752
0bf14ab8
JS
753#if wxUSE_VARIANT
754 wxAny(const wxVariant& variant)
755 {
756 m_type = wxAnyNullValueType;
757 AssignVariant(variant);
758 }
759#endif
760
39601a7f
VZ
761 //@}
762
763 /**
764 Use this template function for checking if this wxAny holds
765 a specific C++ data type.
766
767 @remarks This template function does not work on some older compilers
768 (such as Visual C++ 6.0). For full compiler ccompatibility
769 please use wxANY_CHECK_TYPE(any, T) macro instead.
770
771 @see wxAnyValueType::CheckType()
772 */
773 // FIXME-VC6: remove this hack when VC6 is no longer supported
774 template <typename T>
775 bool CheckType(T* = NULL)
776 {
777 return m_type->CheckType<T>();
778 }
779
780 /**
781 Returns the value type as wxAnyValueType instance.
782
783 @remarks You cannot reliably test whether two wxAnys are of
784 same value type by simply comparing return values
785 of wxAny::GetType(). Instead use
786 wxAnyValueType::CheckType<T>() template function.
787 */
788 const wxAnyValueType* GetType() const
789 {
790 return m_type;
791 }
792
793 /**
794 Tests if wxAny is null (that is, whether there is data).
795 */
796 bool IsNull() const
797 {
798 return (m_type == wxAnyNullValueType);
799 }
800
801 /**
802 Makes wxAny null (that is, clears it).
803 */
804 void MakeNull()
805 {
806 m_type->DeleteValue(m_buffer);
807 m_type = wxAnyNullValueType;
808 }
809
810 //@{
811 /**
812 Assignment operators.
813 */
49efebe2
JS
814 template<typename T>
815 wxAny& operator=(const T &value)
816 {
817 m_type->DeleteValue(m_buffer);
0cc226ad 818 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
49efebe2
JS
819 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
820 return *this;
821 }
822
39601a7f
VZ
823 wxAny& operator=(const wxAny &any)
824 {
2a32b807
PC
825 if (this != &any)
826 AssignAny(any);
39601a7f
VZ
827 return *this;
828 }
829
49efebe2 830#if wxUSE_VARIANT
0bf14ab8
JS
831 wxAny& operator=(const wxVariant &variant)
832 {
833 AssignVariant(variant);
834 return *this;
835 }
836#endif
837
153107b4 838 // These two operators are needed to deal with string literals
39601a7f 839 wxAny& operator=(const char* value)
153107b4
JS
840 {
841 Assign(value);
842 return *this;
843 }
39601a7f 844 wxAny& operator=(const wchar_t* value)
153107b4
JS
845 {
846 Assign(value);
847 return *this;
848 }
39601a7f
VZ
849
850 //@{
851 /**
852 Equality operators.
853 */
854 bool operator==(const wxString& value) const
855 {
153107b4
JS
856 wxString value2;
857 if ( !GetAs(&value2) )
39601a7f 858 return false;
153107b4 859 return value == value2;
39601a7f
VZ
860 }
861
862 bool operator==(const char* value) const
863 { return (*this) == wxString(value); }
864 bool operator==(const wchar_t* value) const
865 { return (*this) == wxString(value); }
866
867 //
868 // We need to implement custom signed/unsigned int equals operators
869 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
870 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
871 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
872 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
873 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
874#ifdef wxLongLong_t
875 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
876#endif
877
878 bool operator==(float value) const
879 {
880 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
881 return false;
882
883 return value ==
884 static_cast<float>
885 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
886 }
887
888 bool operator==(double value) const
889 {
890 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
891 return false;
892
893 return value ==
894 static_cast<double>
895 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
896 }
897
898 bool operator==(bool value) const
899 {
900 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
901 return false;
902
903 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
904 }
905
906 //@}
907
908 //@{
909 /**
910 Inequality operators (implement as template).
911 */
912 template<typename T>
913 bool operator!=(const T& value) const
914 { return !((*this) == value); }
915 //@}
916
917 /**
153107b4
JS
918 This template function converts wxAny into given type. In most cases
919 no type conversion is performed, so if the type is incorrect an
920 assertion failure will occur.
39601a7f 921
153107b4
JS
922 @remarks For conveniency, conversion is done when T is wxString. This
923 is useful when a string literal (which are treated as
924 const char* and const wchar_t*) has been assigned to wxAny.
925
926 This template function may not work properly with Visual C++
927 6. For full compiler compatibility, please use
928 wxANY_AS(any, T) macro instead.
39601a7f
VZ
929 */
930 // FIXME-VC6: remove this hack when VC6 is no longer supported
931 template<typename T>
932 T As(T* = NULL) const
933 {
934 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
01937278 935 {
39601a7f 936 wxFAIL_MSG("Incorrect or non-convertible data type");
01937278
VZ
937 }
938
39601a7f
VZ
939 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
940 }
941
153107b4
JS
942 // Allow easy conversion from 'const char *' etc. to wxString
943 // FIXME-VC6: remove this hack when VC6 is no longer supported
944 //template<>
945 wxString As(wxString*) const
946 {
947 wxString value;
948 if ( !GetAs(&value) )
949 {
950 wxFAIL_MSG("Incorrect or non-convertible data type");
951 }
952 return value;
953 }
954
39601a7f
VZ
955 /**
956 Template function that etrieves and converts the value of this
957 variant to the type that T* value is.
958
959 @return Returns @true if conversion was succesfull.
960 */
961 template<typename T>
962 bool GetAs(T* value) const
963 {
964 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
965 {
966 wxAnyValueType* otherType =
0cc226ad 967 wxAnyValueTypeImpl<T>::sm_instance.get();
39601a7f
VZ
968 wxAnyValueBuffer temp_buf;
969
970 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
971 return false;
972
973 *value =
974 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
975 otherType->DeleteValue(temp_buf);
976
977 return true;
978 }
979 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
980 return true;
981 }
982
0bf14ab8
JS
983#if wxUSE_VARIANT
984 // GetAs() wxVariant specialization
985 bool GetAs(wxVariant* value) const
986 {
987 return wxConvertAnyToVariant(*this, value);
988 }
989#endif
990
39601a7f
VZ
991private:
992 // Assignment functions
45de347c
VZ
993 void AssignAny(const wxAny& any)
994 {
24985a9b
JS
995 // Must delete value - CopyBuffer() never does that
996 m_type->DeleteValue(m_buffer);
997
998 wxAnyValueType* newType = any.m_type;
999
1000 if ( !newType->IsSameType(m_type) )
1001 m_type = newType;
1002
1003 newType->CopyBuffer(any.m_buffer, m_buffer);
45de347c 1004 }
39601a7f 1005
0bf14ab8
JS
1006#if wxUSE_VARIANT
1007 void AssignVariant(const wxVariant& variant)
1008 {
1009 wxVariantData* data = variant.GetData();
1010
1011 if ( data && data->GetAsAny(this) )
1012 return;
1013
1014 m_type->DeleteValue(m_buffer);
1015
1016 if ( variant.IsNull() )
1017 {
1018 // Init as Null
1019 m_type = wxAnyNullValueType;
1020 }
1021 else
1022 {
1023 // If everything else fails, wrap the whole wxVariantData
0cc226ad 1024 m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get();
0bf14ab8
JS
1025 wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
1026 }
1027 }
1028#endif
1029
39601a7f
VZ
1030 template<typename T>
1031 void Assign(const T &value)
1032 {
1033 m_type->DeleteValue(m_buffer);
0cc226ad 1034 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
39601a7f
VZ
1035 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
1036 }
1037
1038 // Data
39601a7f 1039 wxAnyValueBuffer m_buffer;
04110679 1040 wxAnyValueType* m_type;
39601a7f
VZ
1041};
1042
1043
1044//
1045// This method of checking the type is compatible with VC6
1046#define wxANY_CHECK_TYPE(any, T) \
d1358fcb 1047 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
39601a7f
VZ
1048
1049
1050//
1051// This method of getting the value is compatible with VC6
1052#define wxANY_AS(any, T) \
d1358fcb 1053 (any).As(static_cast<T*>(NULL))
39601a7f
VZ
1054
1055
1056template<typename T>
1057inline bool wxAnyValueType::CheckType(T* reserved)
1058{
1059 wxUnusedVar(reserved);
1060 return wxAnyValueTypeImpl<T>::IsSameClass(this);
1061}
1062
1063
1064
1065#endif // wxUSE_ANY
1066
1067#endif // _WX_ANY_H_