]> git.saurik.com Git - wxWidgets.git/blame - include/wx/any.h
Don't use invoking window in wxGTK wxMenuBar implementation.
[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//
153107b4
JS
406// This macro is used in header, but then in source file we must have:
407// WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
39601a7f 408//
153107b4
JS
409#define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
410class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
411 public wxAnyValueTypeImplBase<T> \
412{ \
413 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
414public: \
415 wxAnyValueTypeImpl##TYPENAME() : \
416 wxAnyValueTypeImplBase<T>() { } \
417 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
418 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
419 wxAnyValueType* dstType, \
420 wxAnyValueBuffer& dst) const \
421 { \
422 GV value = GetValue(src); \
423 return CONVFUNC(value, dstType, dst); \
424 } \
425}; \
426template<> \
427class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
428{ \
429public: \
430 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
431 virtual ~wxAnyValueTypeImpl() { } \
432};
39601a7f 433
153107b4
JS
434#define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
435_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
39601a7f 436
153107b4
JS
437#define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
438_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
439 CONVFUNC, const T&) \
39601a7f 440
153107b4
JS
441//
442// String value type
443//
39601a7f 444
153107b4
JS
445// Convert wxString to destination wxAny value type
446extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value,
447 wxAnyValueType* dstType,
448 wxAnyValueBuffer& dst);
449
450WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString)
451WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr,
452 wxAnyConvertString, wxString)
453WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr,
454 wxAnyConvertString, wxString)
39601a7f
VZ
455
456//
457// Bool value type
458//
459template<>
460class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
461 public wxAnyValueTypeImplBase<bool>
462{
463 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
464public:
465 wxAnyValueTypeImpl() :
466 wxAnyValueTypeImplBase<bool>() { }
467 virtual ~wxAnyValueTypeImpl() { }
468
469 virtual bool ConvertValue(const wxAnyValueBuffer& src,
470 wxAnyValueType* dstType,
471 wxAnyValueBuffer& dst) const;
472};
473
474//
475// Floating point value type
476//
477class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
478 public wxAnyValueTypeImplBase<double>
479{
480 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
481public:
482 wxAnyValueTypeImplDouble() :
483 wxAnyValueTypeImplBase<double>() { }
484 virtual ~wxAnyValueTypeImplDouble() { }
485
486 virtual bool ConvertValue(const wxAnyValueBuffer& src,
487 wxAnyValueType* dstType,
488 wxAnyValueBuffer& dst) const;
489};
490
491// WX_ANY_DEFINE_SUB_TYPE requires this
492typedef double wxAnyBaseDoubleType;
493
494WX_ANY_DEFINE_SUB_TYPE(float, Double)
495WX_ANY_DEFINE_SUB_TYPE(double, Double)
496
497
c5fe6a5b
JS
498//
499// Defines a dummy wxAnyValueTypeImpl<> with given export
500// declaration. This is needed if a class is used with
501// wxAny in both user shared library and application.
502//
503#define wxDECLARE_ANY_TYPE(CLS, DECL) \
504template<> \
505class DECL wxAnyValueTypeImpl<CLS> : \
506 public wxAnyValueTypeImplBase<CLS> \
507{ \
508 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
509public: \
510 wxAnyValueTypeImpl() : \
511 wxAnyValueTypeImplBase<CLS>() { } \
512 virtual ~wxAnyValueTypeImpl() { } \
513 \
514 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
515 wxAnyValueType* dstType, \
516 wxAnyValueBuffer& dst) const \
517 { \
518 wxUnusedVar(src); \
519 wxUnusedVar(dstType); \
520 wxUnusedVar(dst); \
521 return false; \
522 } \
523};
524
525
526// Make sure some of wx's own types get the right wxAnyValueType export
527// (this is needed only for types that are referred to from wxBase.
528// currently we may not use any of these types from there, but let's
529// use the macro on at least one to make sure it compiles since we can't
530// really test it properly in unittests since a separate DLL would
531// be needed).
532#if wxUSE_DATETIME
533 #include "wx/datetime.h"
534 wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
535#endif
536
537//#include "wx/object.h"
538//wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
539
540//#include "wx/arrstr.h"
541//wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
542
543
0bf14ab8
JS
544#if wxUSE_VARIANT
545
546class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
547
548// Because of header inter-dependencies, cannot include this earlier
549#include "wx/variant.h"
550
551//
552// wxVariantData* data type implementation. For cases when appropriate
553// wxAny<->wxVariant conversion code is missing.
554//
555
556class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
557 public wxAnyValueTypeImplBase<wxVariantData*>
558{
559 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
560public:
561 wxAnyValueTypeImplVariantData() :
562 wxAnyValueTypeImplBase<wxVariantData*>() { }
563 virtual ~wxAnyValueTypeImplVariantData() { }
564
565 virtual void DeleteValue(wxAnyValueBuffer& buf) const
566 {
567 wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
568 if ( data )
569 data->DecRef();
570 }
571
572 virtual void CopyBuffer(const wxAnyValueBuffer& src,
573 wxAnyValueBuffer& dst) const
574 {
575 wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
576 if ( data )
577 data->IncRef();
578 dst.m_ptr = data;
579 }
580
581 static void SetValue(wxVariantData* value,
582 wxAnyValueBuffer& buf)
583 {
584 value->IncRef();
585 buf.m_ptr = value;
586 }
587
588 static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
589 {
590 return static_cast<wxVariantData*>(buf.m_ptr);
591 }
592
593 virtual bool ConvertValue(const wxAnyValueBuffer& src,
594 wxAnyValueType* dstType,
595 wxAnyValueBuffer& dst) const
596 {
597 wxUnusedVar(src);
598 wxUnusedVar(dstType);
599 wxUnusedVar(dst);
600 return false;
601 }
602};
603
604template<>
605class wxAnyValueTypeImpl<wxVariantData*> :
606 public wxAnyValueTypeImplVariantData
607{
608public:
609 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
610 virtual ~wxAnyValueTypeImpl() { }
611};
612
613#endif // wxUSE_VARIANT
c5fe6a5b 614
39601a7f
VZ
615#ifdef __VISUALC6__
616 // Re-enable useless VC6 warnings
617 #pragma warning (pop)
618#endif
619
620
621/*
622 Let's define a discrete Null value so we don't have to really
623 ever check if wxAny.m_type pointer is NULL or not. This is an
624 optimization, mostly. Implementation of this value type is
625 "hidden" in the source file.
626*/
627extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
628
629
630//
631// We need to implement custom signed/unsigned int equals operators
632// for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
633#define WXANY_IMPLEMENT_INT_EQ_OP(TS, TUS) \
634bool operator==(TS value) const \
635{ \
636 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
637 return (value == static_cast<TS> \
638 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
639 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
640 return (value == static_cast<TS> \
641 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
642 return false; \
643} \
644bool operator==(TUS value) const \
645{ \
646 if ( wxAnyValueTypeImpl<TUS>::IsSameClass(m_type) ) \
647 return (value == static_cast<TUS> \
648 (wxAnyValueTypeImpl<TUS>::GetValue(m_buffer))); \
649 if ( wxAnyValueTypeImpl<TS>::IsSameClass(m_type) ) \
650 return (value == static_cast<TUS> \
651 (wxAnyValueTypeImpl<TS>::GetValue(m_buffer))); \
652 return false; \
653}
654
655
0bf14ab8
JS
656#if wxUSE_VARIANT
657
658// Note that the following functions are implemented outside wxAny class
659// so that it can reside entirely in header and lack the export declaration.
660
661// Helper function used to associate wxAnyValueType with a wxVariantData.
662extern WXDLLIMPEXP_BASE void
663wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
664
665// This function performs main wxAny to wxVariant conversion duties.
666extern WXDLLIMPEXP_BASE bool
667wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
668
669#endif // wxUSE_VARIANT
670
671
39601a7f
VZ
672//
673// The wxAny class represents a container for any type. A variant's value
674// can be changed at run time, possibly to a different type of value.
675//
676// As standard, wxAny can store value of almost any type, in a fairly
677// optimal manner even.
678//
45de347c 679class wxAny
39601a7f
VZ
680{
681public:
682 /**
683 Default constructor.
684 */
685 wxAny()
686 {
687 m_type = wxAnyNullValueType;
688 }
689
690 /**
691 Destructor.
692 */
693 ~wxAny()
694 {
695 m_type->DeleteValue(m_buffer);
696 }
697
698 //@{
699 /**
700 Various constructors.
701 */
ea412ac4
JS
702 template<typename T>
703 wxAny(const T& value)
704 {
705 m_type = wxAnyValueTypeImpl<T>::sm_instance;
706 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
707 }
708
153107b4 709 // These two constructors are needed to deal with string literals
39601a7f
VZ
710 wxAny(const char* value)
711 {
153107b4
JS
712 m_type = wxAnyValueTypeImpl<const char*>::sm_instance;
713 wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
39601a7f
VZ
714 }
715 wxAny(const wchar_t* value)
716 {
153107b4
JS
717 m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance;
718 wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
39601a7f
VZ
719 }
720
721 wxAny(const wxAny& any)
722 {
723 m_type = wxAnyNullValueType;
724 AssignAny(any);
725 }
726
0bf14ab8
JS
727#if wxUSE_VARIANT
728 wxAny(const wxVariant& variant)
729 {
730 m_type = wxAnyNullValueType;
731 AssignVariant(variant);
732 }
733#endif
734
39601a7f
VZ
735 //@}
736
737 /**
738 Use this template function for checking if this wxAny holds
739 a specific C++ data type.
740
741 @remarks This template function does not work on some older compilers
742 (such as Visual C++ 6.0). For full compiler ccompatibility
743 please use wxANY_CHECK_TYPE(any, T) macro instead.
744
745 @see wxAnyValueType::CheckType()
746 */
747 // FIXME-VC6: remove this hack when VC6 is no longer supported
748 template <typename T>
749 bool CheckType(T* = NULL)
750 {
751 return m_type->CheckType<T>();
752 }
753
754 /**
755 Returns the value type as wxAnyValueType instance.
756
757 @remarks You cannot reliably test whether two wxAnys are of
758 same value type by simply comparing return values
759 of wxAny::GetType(). Instead use
760 wxAnyValueType::CheckType<T>() template function.
761 */
762 const wxAnyValueType* GetType() const
763 {
764 return m_type;
765 }
766
767 /**
768 Tests if wxAny is null (that is, whether there is data).
769 */
770 bool IsNull() const
771 {
772 return (m_type == wxAnyNullValueType);
773 }
774
775 /**
776 Makes wxAny null (that is, clears it).
777 */
778 void MakeNull()
779 {
780 m_type->DeleteValue(m_buffer);
781 m_type = wxAnyNullValueType;
782 }
783
784 //@{
785 /**
786 Assignment operators.
787 */
49efebe2
JS
788 template<typename T>
789 wxAny& operator=(const T &value)
790 {
791 m_type->DeleteValue(m_buffer);
792 m_type = wxAnyValueTypeImpl<T>::sm_instance;
793 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
794 return *this;
795 }
796
39601a7f
VZ
797 wxAny& operator=(const wxAny &any)
798 {
2a32b807
PC
799 if (this != &any)
800 AssignAny(any);
39601a7f
VZ
801 return *this;
802 }
803
49efebe2 804#if wxUSE_VARIANT
0bf14ab8
JS
805 wxAny& operator=(const wxVariant &variant)
806 {
807 AssignVariant(variant);
808 return *this;
809 }
810#endif
811
153107b4 812 // These two operators are needed to deal with string literals
39601a7f 813 wxAny& operator=(const char* value)
153107b4
JS
814 {
815 Assign(value);
816 return *this;
817 }
39601a7f 818 wxAny& operator=(const wchar_t* value)
153107b4
JS
819 {
820 Assign(value);
821 return *this;
822 }
39601a7f
VZ
823
824 //@{
825 /**
826 Equality operators.
827 */
828 bool operator==(const wxString& value) const
829 {
153107b4
JS
830 wxString value2;
831 if ( !GetAs(&value2) )
39601a7f 832 return false;
153107b4 833 return value == value2;
39601a7f
VZ
834 }
835
836 bool operator==(const char* value) const
837 { return (*this) == wxString(value); }
838 bool operator==(const wchar_t* value) const
839 { return (*this) == wxString(value); }
840
841 //
842 // We need to implement custom signed/unsigned int equals operators
843 // for signed/unsigned (eg. wxAny(128UL) == 128L) comparisons to work.
844 WXANY_IMPLEMENT_INT_EQ_OP(signed char, unsigned char)
845 WXANY_IMPLEMENT_INT_EQ_OP(signed short, unsigned short)
846 WXANY_IMPLEMENT_INT_EQ_OP(signed int, unsigned int)
847 WXANY_IMPLEMENT_INT_EQ_OP(signed long, unsigned long)
848#ifdef wxLongLong_t
849 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
850#endif
851
852 bool operator==(float value) const
853 {
854 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
855 return false;
856
857 return value ==
858 static_cast<float>
859 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
860 }
861
862 bool operator==(double value) const
863 {
864 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
865 return false;
866
867 return value ==
868 static_cast<double>
869 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
870 }
871
872 bool operator==(bool value) const
873 {
874 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
875 return false;
876
877 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
878 }
879
880 //@}
881
882 //@{
883 /**
884 Inequality operators (implement as template).
885 */
886 template<typename T>
887 bool operator!=(const T& value) const
888 { return !((*this) == value); }
889 //@}
890
891 /**
153107b4
JS
892 This template function converts wxAny into given type. In most cases
893 no type conversion is performed, so if the type is incorrect an
894 assertion failure will occur.
39601a7f 895
153107b4
JS
896 @remarks For conveniency, conversion is done when T is wxString. This
897 is useful when a string literal (which are treated as
898 const char* and const wchar_t*) has been assigned to wxAny.
899
900 This template function may not work properly with Visual C++
901 6. For full compiler compatibility, please use
902 wxANY_AS(any, T) macro instead.
39601a7f
VZ
903 */
904 // FIXME-VC6: remove this hack when VC6 is no longer supported
905 template<typename T>
906 T As(T* = NULL) const
907 {
908 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
01937278 909 {
39601a7f 910 wxFAIL_MSG("Incorrect or non-convertible data type");
01937278
VZ
911 }
912
39601a7f
VZ
913 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
914 }
915
153107b4
JS
916 // Allow easy conversion from 'const char *' etc. to wxString
917 // FIXME-VC6: remove this hack when VC6 is no longer supported
918 //template<>
919 wxString As(wxString*) const
920 {
921 wxString value;
922 if ( !GetAs(&value) )
923 {
924 wxFAIL_MSG("Incorrect or non-convertible data type");
925 }
926 return value;
927 }
928
39601a7f
VZ
929 /**
930 Template function that etrieves and converts the value of this
931 variant to the type that T* value is.
932
933 @return Returns @true if conversion was succesfull.
934 */
935 template<typename T>
936 bool GetAs(T* value) const
937 {
938 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
939 {
940 wxAnyValueType* otherType =
941 wxAnyValueTypeImpl<T>::sm_instance;
942 wxAnyValueBuffer temp_buf;
943
944 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
945 return false;
946
947 *value =
948 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
949 otherType->DeleteValue(temp_buf);
950
951 return true;
952 }
953 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
954 return true;
955 }
956
0bf14ab8
JS
957#if wxUSE_VARIANT
958 // GetAs() wxVariant specialization
959 bool GetAs(wxVariant* value) const
960 {
961 return wxConvertAnyToVariant(*this, value);
962 }
963#endif
964
39601a7f
VZ
965private:
966 // Assignment functions
45de347c
VZ
967 void AssignAny(const wxAny& any)
968 {
24985a9b
JS
969 // Must delete value - CopyBuffer() never does that
970 m_type->DeleteValue(m_buffer);
971
972 wxAnyValueType* newType = any.m_type;
973
974 if ( !newType->IsSameType(m_type) )
975 m_type = newType;
976
977 newType->CopyBuffer(any.m_buffer, m_buffer);
45de347c 978 }
39601a7f 979
0bf14ab8
JS
980#if wxUSE_VARIANT
981 void AssignVariant(const wxVariant& variant)
982 {
983 wxVariantData* data = variant.GetData();
984
985 if ( data && data->GetAsAny(this) )
986 return;
987
988 m_type->DeleteValue(m_buffer);
989
990 if ( variant.IsNull() )
991 {
992 // Init as Null
993 m_type = wxAnyNullValueType;
994 }
995 else
996 {
997 // If everything else fails, wrap the whole wxVariantData
998 m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance;
999 wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
1000 }
1001 }
1002#endif
1003
39601a7f
VZ
1004 template<typename T>
1005 void Assign(const T &value)
1006 {
1007 m_type->DeleteValue(m_buffer);
1008 m_type = wxAnyValueTypeImpl<T>::sm_instance;
1009 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
1010 }
1011
1012 // Data
39601a7f 1013 wxAnyValueBuffer m_buffer;
04110679 1014 wxAnyValueType* m_type;
39601a7f
VZ
1015};
1016
1017
1018//
1019// This method of checking the type is compatible with VC6
1020#define wxANY_CHECK_TYPE(any, T) \
d1358fcb 1021 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
39601a7f
VZ
1022
1023
1024//
1025// This method of getting the value is compatible with VC6
1026#define wxANY_AS(any, T) \
d1358fcb 1027 (any).As(static_cast<T*>(NULL))
39601a7f
VZ
1028
1029
1030template<typename T>
1031inline bool wxAnyValueType::CheckType(T* reserved)
1032{
1033 wxUnusedVar(reserved);
1034 return wxAnyValueTypeImpl<T>::IsSameClass(this);
1035}
1036
1037
1038
1039#endif // wxUSE_ANY
1040
1041#endif // _WX_ANY_H_