]> git.saurik.com Git - wxWidgets.git/blame - include/wx/any.h
Make wxChoice and wxComboBox behaviour same as in native controls in wxMSW.
[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
94cd7b00 19#include <new> // for placement new
39601a7f 20#include "wx/string.h"
39601a7f 21#include "wx/meta/if.h"
7db064f6 22#include "wx/typeinfo.h"
f41d5991 23#include "wx/list.h"
39601a7f
VZ
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
f41d5991 107 (such as Visual C++ 6.0). For full compiler compatibility
39601a7f
VZ
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>
49ddcdf9 115 bool CheckType(T* reserved = NULL) const;
cbca59a8
SC
116
117#if wxUSE_EXTENDED_RTTI
118 virtual const wxTypeInfo* GetTypeInfo() const = 0;
119#endif
39601a7f
VZ
120private:
121};
122
0cc226ad
JS
123
124//
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.
131//
132class wxAnyValueTypeScopedPtr
133{
134public:
135 wxAnyValueTypeScopedPtr(wxAnyValueType* ptr) : m_ptr(ptr) { }
136 ~wxAnyValueTypeScopedPtr() { delete m_ptr; }
137 wxAnyValueType* get() const { return m_ptr; }
138private:
139 wxAnyValueType* m_ptr;
140};
141
142
39601a7f
VZ
143//
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)
147
39601a7f
VZ
148
149/**
150 Helper macro for defining user value types.
151
7db064f6
JS
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.
0cc226ad
JS
156
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).
39601a7f
VZ
161*/
162#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
163 friend class wxAny; \
7db064f6 164 WX_DECLARE_TYPEINFO_INLINE(CLS) \
39601a7f 165public: \
39601a7f
VZ
166 static bool IsSameClass(const wxAnyValueType* otherType) \
167 { \
0cc226ad 168 return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
39601a7f
VZ
169 } \
170 virtual bool IsSameType(const wxAnyValueType* otherType) const \
171 { \
172 return IsSameClass(otherType); \
173 } \
174private: \
0cc226ad 175 static wxAnyValueTypeScopedPtr sm_instance; \
39601a7f
VZ
176public: \
177 static wxAnyValueType* GetInstance() \
178 { \
0cc226ad 179 return sm_instance.get(); \
39601a7f
VZ
180 }
181
182
183#define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
0cc226ad 184wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
39601a7f
VZ
185
186
187#ifdef __VISUALC6__
188 // "non dll-interface class 'xxx' used as base interface
189 #pragma warning (push)
190 #pragma warning (disable:4275)
191#endif
192
193/**
194 Following are helper classes for the wxAnyValueTypeImplBase.
195*/
196namespace wxPrivate
197{
198
199template<typename T>
94cd7b00 200class wxAnyValueTypeOpsInplace
39601a7f
VZ
201{
202public:
203 static void DeleteValue(wxAnyValueBuffer& buf)
204 {
94cd7b00
JS
205 T* value = reinterpret_cast<T*>(&buf.m_buffer[0]);
206 value->~T();
207
208 // Some compiler may given 'unused variable' warnings without this
209 wxUnusedVar(value);
39601a7f
VZ
210 }
211
212 static void SetValue(const T& value,
213 wxAnyValueBuffer& buf)
214 {
94cd7b00
JS
215 // Use placement new
216 void* const place = buf.m_buffer;
217 ::new(place) T(value);
39601a7f
VZ
218 }
219
220 static const T& GetValue(const wxAnyValueBuffer& buf)
221 {
f41d5991 222 // Breaking this code into two lines should suppress
1237a25b
JS
223 // GCC's 'type-punned pointer will break strict-aliasing rules'
224 // warning.
225 const T* value = reinterpret_cast<const T*>(&buf.m_buffer[0]);
226 return *value;
39601a7f
VZ
227 }
228};
229
230
231template<typename T>
232class wxAnyValueTypeOpsGeneric
233{
234public:
235 template<typename T2>
236 class DataHolder
237 {
238 public:
239 DataHolder(const T2& value)
240 {
241 m_value = value;
242 }
243 virtual ~DataHolder() { }
244
245 T2 m_value;
246 private:
247 wxDECLARE_NO_COPY_CLASS(DataHolder);
248 };
249
250 static void DeleteValue(wxAnyValueBuffer& buf)
251 {
252 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
253 delete holder;
254 }
255
256 static void SetValue(const T& value,
257 wxAnyValueBuffer& buf)
258 {
259 DataHolder<T>* holder = new DataHolder<T>(value);
260 buf.m_ptr = holder;
261 }
262
263 static const T& GetValue(const wxAnyValueBuffer& buf)
264 {
265 DataHolder<T>* holder = static_cast<DataHolder<T>*>(buf.m_ptr);
266 return holder->m_value;
267 }
268};
269
270} // namespace wxPrivate
271
272
273/**
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.
279*/
280template<typename T>
281class wxAnyValueTypeImplBase : public wxAnyValueType
282{
94cd7b00
JS
283 typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE,
284 wxPrivate::wxAnyValueTypeOpsInplace<T>,
39601a7f
VZ
285 wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value
286 Ops;
287
288public:
289 wxAnyValueTypeImplBase() : wxAnyValueType() { }
290 virtual ~wxAnyValueTypeImplBase() { }
291
292 virtual void DeleteValue(wxAnyValueBuffer& buf) const
293 {
294 Ops::DeleteValue(buf);
39601a7f
VZ
295 }
296
297 virtual void CopyBuffer(const wxAnyValueBuffer& src,
298 wxAnyValueBuffer& dst) const
299 {
39601a7f
VZ
300 Ops::SetValue(Ops::GetValue(src), dst);
301 }
302
303 /**
304 It is important to reimplement this in any specialized template
305 classes that inherit from wxAnyValueTypeImplBase.
306 */
307 static void SetValue(const T& value,
308 wxAnyValueBuffer& buf)
309 {
310 Ops::SetValue(value, buf);
311 }
312
313 /**
314 It is important to reimplement this in any specialized template
315 classes that inherit from wxAnyValueTypeImplBase.
316 */
317 static const T& GetValue(const wxAnyValueBuffer& buf)
318 {
319 return Ops::GetValue(buf);
320 }
cbca59a8
SC
321#if wxUSE_EXTENDED_RTTI
322 virtual const wxTypeInfo* GetTypeInfo() const
323 {
324 return wxGetTypeInfo((T*)NULL);
325 }
326#endif
39601a7f
VZ
327};
328
329
330/*
331 Generic value type template. Note that bulk of the implementation
332 resides in wxAnyValueTypeImplBase.
333*/
334template<typename T>
335class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T>
336{
337 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>)
338public:
339 wxAnyValueTypeImpl() : wxAnyValueTypeImplBase<T>() { }
340 virtual ~wxAnyValueTypeImpl() { }
341
342 virtual bool ConvertValue(const wxAnyValueBuffer& src,
343 wxAnyValueType* dstType,
344 wxAnyValueBuffer& dst) const
345 {
346 wxUnusedVar(src);
347 wxUnusedVar(dstType);
348 wxUnusedVar(dst);
349 return false;
350 }
351};
352
353template<typename T>
0cc226ad 354wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>();
39601a7f
VZ
355
356
357//
358// Helper macro for using same base value type implementation for multiple
359// actual C++ data types.
360//
cbca59a8 361#define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
39601a7f
VZ
362template<> \
363class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
364{ \
365 typedef wxAnyBase##CLSTYPE##Type UseDataType; \
366public: \
367 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
368 virtual ~wxAnyValueTypeImpl() { } \
369 static void SetValue(const T& value, wxAnyValueBuffer& buf) \
370 { \
1237a25b
JS
371 void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
372 UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
373 *dptr = static_cast<UseDataType>(value); \
39601a7f
VZ
374 } \
375 static T GetValue(const wxAnyValueBuffer& buf) \
376 { \
1237a25b
JS
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); \
cbca59a8
SC
382 }
383
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 \
388 { \
389 return wxGetTypeInfo((T*)NULL); \
39601a7f
VZ
390 } \
391};
cbca59a8
SC
392#else
393#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
394_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
395};
396#endif
39601a7f
VZ
397
398//
399// Integer value types
400//
401
402#ifdef wxLongLong_t
403 typedef wxLongLong_t wxAnyBaseIntType;
404 typedef wxULongLong_t wxAnyBaseUintType;
405#else
406 typedef long wxAnyBaseIntType;
407 typedef unsigned long wxAnyBaseUintType;
408#endif
409
410
411class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt :
412 public wxAnyValueTypeImplBase<wxAnyBaseIntType>
413{
414 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
415public:
416 wxAnyValueTypeImplInt() :
417 wxAnyValueTypeImplBase<wxAnyBaseIntType>() { }
418 virtual ~wxAnyValueTypeImplInt() { }
419
420 virtual bool ConvertValue(const wxAnyValueBuffer& src,
421 wxAnyValueType* dstType,
422 wxAnyValueBuffer& dst) const;
423};
424
425
426class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint :
427 public wxAnyValueTypeImplBase<wxAnyBaseUintType>
428{
429 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
430public:
431 wxAnyValueTypeImplUint() :
432 wxAnyValueTypeImplBase<wxAnyBaseUintType>() { }
433 virtual ~wxAnyValueTypeImplUint() { }
434
435 virtual bool ConvertValue(const wxAnyValueBuffer& src,
436 wxAnyValueType* dstType,
437 wxAnyValueBuffer& dst) const;
438};
439
440
441WX_ANY_DEFINE_SUB_TYPE(signed long, Int)
442WX_ANY_DEFINE_SUB_TYPE(signed int, Int)
443WX_ANY_DEFINE_SUB_TYPE(signed short, Int)
444WX_ANY_DEFINE_SUB_TYPE(signed char, Int)
445#ifdef wxLongLong_t
446WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int)
447#endif
448
449WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint)
450WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint)
451WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint)
452WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint)
453#ifdef wxLongLong_t
454WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint)
455#endif
456
457
458//
153107b4
JS
459// This macro is used in header, but then in source file we must have:
460// WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
39601a7f 461//
153107b4
JS
462#define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
463class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
464 public wxAnyValueTypeImplBase<T> \
465{ \
466 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
467public: \
468 wxAnyValueTypeImpl##TYPENAME() : \
469 wxAnyValueTypeImplBase<T>() { } \
470 virtual ~wxAnyValueTypeImpl##TYPENAME() { } \
471 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
472 wxAnyValueType* dstType, \
473 wxAnyValueBuffer& dst) const \
474 { \
475 GV value = GetValue(src); \
476 return CONVFUNC(value, dstType, dst); \
477 } \
478}; \
479template<> \
480class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
481{ \
482public: \
483 wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
484 virtual ~wxAnyValueTypeImpl() { } \
485};
39601a7f 486
153107b4
JS
487#define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
488_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
39601a7f 489
153107b4
JS
490#define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
491_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
492 CONVFUNC, const T&) \
39601a7f 493
153107b4
JS
494//
495// String value type
496//
39601a7f 497
153107b4
JS
498// Convert wxString to destination wxAny value type
499extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value,
500 wxAnyValueType* dstType,
501 wxAnyValueBuffer& dst);
502
503WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString)
504WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr,
505 wxAnyConvertString, wxString)
506WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr,
507 wxAnyConvertString, wxString)
39601a7f
VZ
508
509//
510// Bool value type
511//
512template<>
513class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> :
514 public wxAnyValueTypeImplBase<bool>
515{
516 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
517public:
518 wxAnyValueTypeImpl() :
519 wxAnyValueTypeImplBase<bool>() { }
520 virtual ~wxAnyValueTypeImpl() { }
521
522 virtual bool ConvertValue(const wxAnyValueBuffer& src,
523 wxAnyValueType* dstType,
524 wxAnyValueBuffer& dst) const;
525};
526
527//
528// Floating point value type
529//
530class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble :
531 public wxAnyValueTypeImplBase<double>
532{
533 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
534public:
535 wxAnyValueTypeImplDouble() :
536 wxAnyValueTypeImplBase<double>() { }
537 virtual ~wxAnyValueTypeImplDouble() { }
538
539 virtual bool ConvertValue(const wxAnyValueBuffer& src,
540 wxAnyValueType* dstType,
541 wxAnyValueBuffer& dst) const;
542};
543
544// WX_ANY_DEFINE_SUB_TYPE requires this
545typedef double wxAnyBaseDoubleType;
546
547WX_ANY_DEFINE_SUB_TYPE(float, Double)
548WX_ANY_DEFINE_SUB_TYPE(double, Double)
549
550
c5fe6a5b
JS
551//
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.
555//
556#define wxDECLARE_ANY_TYPE(CLS, DECL) \
557template<> \
558class DECL wxAnyValueTypeImpl<CLS> : \
559 public wxAnyValueTypeImplBase<CLS> \
560{ \
561 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
562public: \
563 wxAnyValueTypeImpl() : \
564 wxAnyValueTypeImplBase<CLS>() { } \
565 virtual ~wxAnyValueTypeImpl() { } \
566 \
567 virtual bool ConvertValue(const wxAnyValueBuffer& src, \
568 wxAnyValueType* dstType, \
569 wxAnyValueBuffer& dst) const \
570 { \
571 wxUnusedVar(src); \
572 wxUnusedVar(dstType); \
573 wxUnusedVar(dst); \
574 return false; \
575 } \
576};
577
578
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
f41d5991 583// really test it properly in unit tests since a separate DLL would
c5fe6a5b
JS
584// be needed).
585#if wxUSE_DATETIME
586 #include "wx/datetime.h"
587 wxDECLARE_ANY_TYPE(wxDateTime, WXDLLIMPEXP_BASE)
588#endif
589
590//#include "wx/object.h"
591//wxDECLARE_ANY_TYPE(wxObject*, WXDLLIMPEXP_BASE)
592
593//#include "wx/arrstr.h"
594//wxDECLARE_ANY_TYPE(wxArrayString, WXDLLIMPEXP_BASE)
595
596
0bf14ab8
JS
597#if wxUSE_VARIANT
598
599class WXDLLIMPEXP_FWD_BASE wxAnyToVariantRegistration;
600
601// Because of header inter-dependencies, cannot include this earlier
602#include "wx/variant.h"
603
604//
605// wxVariantData* data type implementation. For cases when appropriate
606// wxAny<->wxVariant conversion code is missing.
607//
608
609class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData :
610 public wxAnyValueTypeImplBase<wxVariantData*>
611{
612 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData)
613public:
614 wxAnyValueTypeImplVariantData() :
615 wxAnyValueTypeImplBase<wxVariantData*>() { }
616 virtual ~wxAnyValueTypeImplVariantData() { }
617
618 virtual void DeleteValue(wxAnyValueBuffer& buf) const
619 {
620 wxVariantData* data = static_cast<wxVariantData*>(buf.m_ptr);
621 if ( data )
622 data->DecRef();
623 }
624
625 virtual void CopyBuffer(const wxAnyValueBuffer& src,
626 wxAnyValueBuffer& dst) const
627 {
628 wxVariantData* data = static_cast<wxVariantData*>(src.m_ptr);
629 if ( data )
630 data->IncRef();
631 dst.m_ptr = data;
632 }
633
634 static void SetValue(wxVariantData* value,
635 wxAnyValueBuffer& buf)
636 {
637 value->IncRef();
638 buf.m_ptr = value;
639 }
640
641 static wxVariantData* GetValue(const wxAnyValueBuffer& buf)
642 {
643 return static_cast<wxVariantData*>(buf.m_ptr);
644 }
645
646 virtual bool ConvertValue(const wxAnyValueBuffer& src,
647 wxAnyValueType* dstType,
648 wxAnyValueBuffer& dst) const
649 {
650 wxUnusedVar(src);
651 wxUnusedVar(dstType);
652 wxUnusedVar(dst);
653 return false;
654 }
655};
656
657template<>
658class wxAnyValueTypeImpl<wxVariantData*> :
659 public wxAnyValueTypeImplVariantData
660{
661public:
662 wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { }
663 virtual ~wxAnyValueTypeImpl() { }
664};
665
666#endif // wxUSE_VARIANT
c5fe6a5b 667
39601a7f
VZ
668#ifdef __VISUALC6__
669 // Re-enable useless VC6 warnings
670 #pragma warning (pop)
671#endif
672
673
674/*
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.
679*/
680extern WXDLLIMPEXP_DATA_BASE(wxAnyValueType*) wxAnyNullValueType;
681
682
683//
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) \
687bool operator==(TS value) const \
688{ \
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))); \
695 return false; \
696} \
697bool operator==(TUS value) const \
698{ \
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))); \
705 return false; \
706}
707
708
0bf14ab8
JS
709#if wxUSE_VARIANT
710
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.
713
714// Helper function used to associate wxAnyValueType with a wxVariantData.
715extern WXDLLIMPEXP_BASE void
716wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg);
717
718// This function performs main wxAny to wxVariant conversion duties.
719extern WXDLLIMPEXP_BASE bool
720wxConvertAnyToVariant(const wxAny& any, wxVariant* variant);
721
722#endif // wxUSE_VARIANT
723
724
39601a7f
VZ
725//
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.
728//
729// As standard, wxAny can store value of almost any type, in a fairly
730// optimal manner even.
731//
45de347c 732class wxAny
39601a7f
VZ
733{
734public:
735 /**
736 Default constructor.
737 */
738 wxAny()
739 {
740 m_type = wxAnyNullValueType;
741 }
742
743 /**
744 Destructor.
745 */
746 ~wxAny()
747 {
748 m_type->DeleteValue(m_buffer);
749 }
750
751 //@{
752 /**
753 Various constructors.
754 */
ea412ac4
JS
755 template<typename T>
756 wxAny(const T& value)
757 {
0cc226ad 758 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
ea412ac4
JS
759 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
760 }
761
153107b4 762 // These two constructors are needed to deal with string literals
39601a7f
VZ
763 wxAny(const char* value)
764 {
0cc226ad 765 m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get();
153107b4 766 wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer);
39601a7f
VZ
767 }
768 wxAny(const wchar_t* value)
769 {
0cc226ad 770 m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get();
153107b4 771 wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer);
39601a7f
VZ
772 }
773
774 wxAny(const wxAny& any)
775 {
776 m_type = wxAnyNullValueType;
777 AssignAny(any);
778 }
779
0bf14ab8
JS
780#if wxUSE_VARIANT
781 wxAny(const wxVariant& variant)
782 {
783 m_type = wxAnyNullValueType;
784 AssignVariant(variant);
785 }
786#endif
787
39601a7f
VZ
788 //@}
789
790 /**
791 Use this template function for checking if this wxAny holds
792 a specific C++ data type.
793
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.
797
798 @see wxAnyValueType::CheckType()
799 */
800 // FIXME-VC6: remove this hack when VC6 is no longer supported
801 template <typename T>
49ddcdf9 802 bool CheckType(T* = NULL) const
39601a7f
VZ
803 {
804 return m_type->CheckType<T>();
805 }
806
807 /**
808 Returns the value type as wxAnyValueType instance.
809
810 @remarks You cannot reliably test whether two wxAnys are of
811 same value type by simply comparing return values
f1156cbb
JS
812 of wxAny::GetType(). Instead, use wxAny::HasSameType().
813
814 @see HasSameType()
39601a7f
VZ
815 */
816 const wxAnyValueType* GetType() const
817 {
818 return m_type;
819 }
820
f1156cbb
JS
821 /**
822 Returns @true if this and another wxAny have the same
823 value type.
824 */
825 bool HasSameType(const wxAny& other) const
826 {
827 return GetType()->IsSameType(other.GetType());
828 }
829
39601a7f 830 /**
79c60a3e 831 Tests if wxAny is null (that is, whether there is no data).
39601a7f
VZ
832 */
833 bool IsNull() const
834 {
835 return (m_type == wxAnyNullValueType);
836 }
837
838 /**
839 Makes wxAny null (that is, clears it).
840 */
841 void MakeNull()
842 {
843 m_type->DeleteValue(m_buffer);
844 m_type = wxAnyNullValueType;
845 }
846
847 //@{
848 /**
849 Assignment operators.
850 */
49efebe2
JS
851 template<typename T>
852 wxAny& operator=(const T &value)
853 {
854 m_type->DeleteValue(m_buffer);
0cc226ad 855 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
49efebe2
JS
856 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
857 return *this;
858 }
859
39601a7f
VZ
860 wxAny& operator=(const wxAny &any)
861 {
2a32b807
PC
862 if (this != &any)
863 AssignAny(any);
39601a7f
VZ
864 return *this;
865 }
866
49efebe2 867#if wxUSE_VARIANT
0bf14ab8
JS
868 wxAny& operator=(const wxVariant &variant)
869 {
870 AssignVariant(variant);
871 return *this;
872 }
873#endif
874
153107b4 875 // These two operators are needed to deal with string literals
39601a7f 876 wxAny& operator=(const char* value)
153107b4
JS
877 {
878 Assign(value);
879 return *this;
880 }
39601a7f 881 wxAny& operator=(const wchar_t* value)
153107b4
JS
882 {
883 Assign(value);
884 return *this;
885 }
39601a7f
VZ
886
887 //@{
888 /**
889 Equality operators.
890 */
891 bool operator==(const wxString& value) const
892 {
153107b4
JS
893 wxString value2;
894 if ( !GetAs(&value2) )
39601a7f 895 return false;
153107b4 896 return value == value2;
39601a7f
VZ
897 }
898
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); }
903
904 //
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)
911#ifdef wxLongLong_t
912 WXANY_IMPLEMENT_INT_EQ_OP(wxLongLong_t, wxULongLong_t)
913#endif
914
915 bool operator==(float value) const
916 {
917 if ( !wxAnyValueTypeImpl<float>::IsSameClass(m_type) )
918 return false;
919
920 return value ==
921 static_cast<float>
922 (wxAnyValueTypeImpl<float>::GetValue(m_buffer));
923 }
924
925 bool operator==(double value) const
926 {
927 if ( !wxAnyValueTypeImpl<double>::IsSameClass(m_type) )
928 return false;
929
930 return value ==
931 static_cast<double>
932 (wxAnyValueTypeImpl<double>::GetValue(m_buffer));
933 }
934
935 bool operator==(bool value) const
936 {
937 if ( !wxAnyValueTypeImpl<bool>::IsSameClass(m_type) )
938 return false;
939
940 return value == (wxAnyValueTypeImpl<bool>::GetValue(m_buffer));
941 }
942
943 //@}
944
945 //@{
946 /**
947 Inequality operators (implement as template).
948 */
949 template<typename T>
950 bool operator!=(const T& value) const
951 { return !((*this) == value); }
952 //@}
953
954 /**
153107b4
JS
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.
39601a7f 958
f41d5991 959 @remarks For convenience, conversion is done when T is wxString. This
153107b4
JS
960 is useful when a string literal (which are treated as
961 const char* and const wchar_t*) has been assigned to wxAny.
962
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.
39601a7f
VZ
966 */
967 // FIXME-VC6: remove this hack when VC6 is no longer supported
968 template<typename T>
969 T As(T* = NULL) const
970 {
971 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
01937278 972 {
39601a7f 973 wxFAIL_MSG("Incorrect or non-convertible data type");
01937278
VZ
974 }
975
39601a7f
VZ
976 return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
977 }
978
153107b4
JS
979 // Allow easy conversion from 'const char *' etc. to wxString
980 // FIXME-VC6: remove this hack when VC6 is no longer supported
981 //template<>
982 wxString As(wxString*) const
983 {
984 wxString value;
985 if ( !GetAs(&value) )
986 {
987 wxFAIL_MSG("Incorrect or non-convertible data type");
988 }
989 return value;
990 }
991
cbca59a8
SC
992#if wxUSE_EXTENDED_RTTI
993 const wxTypeInfo* GetTypeInfo() const
994 {
995 return m_type->GetTypeInfo();
996 }
997#endif
39601a7f 998 /**
f41d5991 999 Template function that retrieves and converts the value of this
39601a7f
VZ
1000 variant to the type that T* value is.
1001
f41d5991 1002 @return Returns @true if conversion was successful.
39601a7f
VZ
1003 */
1004 template<typename T>
1005 bool GetAs(T* value) const
1006 {
1007 if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) )
1008 {
1009 wxAnyValueType* otherType =
0cc226ad 1010 wxAnyValueTypeImpl<T>::sm_instance.get();
39601a7f
VZ
1011 wxAnyValueBuffer temp_buf;
1012
1013 if ( !m_type->ConvertValue(m_buffer, otherType, temp_buf) )
1014 return false;
1015
1016 *value =
1017 static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(temp_buf));
1018 otherType->DeleteValue(temp_buf);
1019
1020 return true;
1021 }
1022 *value = static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer));
1023 return true;
1024 }
1025
0bf14ab8
JS
1026#if wxUSE_VARIANT
1027 // GetAs() wxVariant specialization
1028 bool GetAs(wxVariant* value) const
1029 {
1030 return wxConvertAnyToVariant(*this, value);
1031 }
1032#endif
1033
39601a7f
VZ
1034private:
1035 // Assignment functions
45de347c
VZ
1036 void AssignAny(const wxAny& any)
1037 {
986a5956
SC
1038 // Must delete value - CopyBuffer() never does that
1039 m_type->DeleteValue(m_buffer);
24985a9b
JS
1040
1041 wxAnyValueType* newType = any.m_type;
1042
986a5956 1043 if ( !newType->IsSameType(m_type) )
24985a9b
JS
1044 m_type = newType;
1045
1046 newType->CopyBuffer(any.m_buffer, m_buffer);
45de347c 1047 }
39601a7f 1048
0bf14ab8
JS
1049#if wxUSE_VARIANT
1050 void AssignVariant(const wxVariant& variant)
1051 {
1052 wxVariantData* data = variant.GetData();
1053
1054 if ( data && data->GetAsAny(this) )
1055 return;
1056
1057 m_type->DeleteValue(m_buffer);
1058
1059 if ( variant.IsNull() )
1060 {
1061 // Init as Null
1062 m_type = wxAnyNullValueType;
1063 }
1064 else
1065 {
1066 // If everything else fails, wrap the whole wxVariantData
0cc226ad 1067 m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get();
0bf14ab8
JS
1068 wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer);
1069 }
1070 }
1071#endif
1072
39601a7f
VZ
1073 template<typename T>
1074 void Assign(const T &value)
1075 {
1076 m_type->DeleteValue(m_buffer);
0cc226ad 1077 m_type = wxAnyValueTypeImpl<T>::sm_instance.get();
39601a7f
VZ
1078 wxAnyValueTypeImpl<T>::SetValue(value, m_buffer);
1079 }
1080
1081 // Data
39601a7f 1082 wxAnyValueBuffer m_buffer;
04110679 1083 wxAnyValueType* m_type;
39601a7f
VZ
1084};
1085
1086
1087//
1088// This method of checking the type is compatible with VC6
1089#define wxANY_CHECK_TYPE(any, T) \
d1358fcb 1090 wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
39601a7f
VZ
1091
1092
1093//
1094// This method of getting the value is compatible with VC6
1095#define wxANY_AS(any, T) \
d1358fcb 1096 (any).As(static_cast<T*>(NULL))
39601a7f
VZ
1097
1098
1099template<typename T>
49ddcdf9 1100inline bool wxAnyValueType::CheckType(T* reserved) const
39601a7f
VZ
1101{
1102 wxUnusedVar(reserved);
1103 return wxAnyValueTypeImpl<T>::IsSameClass(this);
1104}
1105
f41d5991 1106WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE);
39601a7f
VZ
1107
1108#endif // wxUSE_ANY
1109
1110#endif // _WX_ANY_H_