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