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