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