1
by Brian Sidebotham
Initial import into Bazaar |
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: any.h 66621 2011-01-07 17:22:59Z SC $
|
|
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 <new> // for placement new |
|
20 |
#include "wx/string.h" |
|
21 |
#include "wx/meta/if.h" |
|
22 |
#include "wx/typeinfo.h" |
|
23 |
#include "wx/list.h" |
|
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 compatibility
|
|
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 |
||
117 |
#if wxUSE_EXTENDED_RTTI
|
|
118 |
virtual const wxTypeInfo* GetTypeInfo() const = 0; |
|
119 |
#endif
|
|
120 |
private: |
|
121 |
};
|
|
122 |
||
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 |
//
|
|
132 |
class wxAnyValueTypeScopedPtr |
|
133 |
{
|
|
134 |
public: |
|
135 |
wxAnyValueTypeScopedPtr(wxAnyValueType* ptr) : m_ptr(ptr) { } |
|
136 |
~wxAnyValueTypeScopedPtr() { delete m_ptr; } |
|
137 |
wxAnyValueType* get() const { return m_ptr; } |
|
138 |
private: |
|
139 |
wxAnyValueType* m_ptr; |
|
140 |
};
|
|
141 |
||
142 |
||
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 |
||
148 |
||
149 |
/**
|
|
150 |
Helper macro for defining user value types.
|
|
151 |
||
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.
|
|
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).
|
|
161 |
*/
|
|
162 |
#define WX_DECLARE_ANY_VALUE_TYPE(CLS) \
|
|
163 |
friend class wxAny; \
|
|
164 |
WX_DECLARE_TYPEINFO_INLINE(CLS) \
|
|
165 |
public: \
|
|
166 |
static bool IsSameClass(const wxAnyValueType* otherType) \
|
|
167 |
{ \
|
|
168 |
return wxTypeId(*sm_instance.get()) == wxTypeId(*otherType); \
|
|
169 |
} \
|
|
170 |
virtual bool IsSameType(const wxAnyValueType* otherType) const \
|
|
171 |
{ \
|
|
172 |
return IsSameClass(otherType); \
|
|
173 |
} \
|
|
174 |
private: \
|
|
175 |
static wxAnyValueTypeScopedPtr sm_instance; \
|
|
176 |
public: \
|
|
177 |
static wxAnyValueType* GetInstance() \
|
|
178 |
{ \
|
|
179 |
return sm_instance.get(); \
|
|
180 |
}
|
|
181 |
||
182 |
||
183 |
#define WX_IMPLEMENT_ANY_VALUE_TYPE(CLS) \
|
|
184 |
wxAnyValueTypeScopedPtr CLS::sm_instance(new CLS());
|
|
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 |
*/
|
|
196 |
namespace wxPrivate |
|
197 |
{
|
|
198 |
||
199 |
template<typename T> |
|
200 |
class wxAnyValueTypeOpsInplace |
|
201 |
{
|
|
202 |
public: |
|
203 |
static void DeleteValue(wxAnyValueBuffer& buf) |
|
204 |
{
|
|
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); |
|
210 |
}
|
|
211 |
||
212 |
static void SetValue(const T& value, |
|
213 |
wxAnyValueBuffer& buf) |
|
214 |
{
|
|
215 |
// Use placement new
|
|
216 |
void* const place = buf.m_buffer; |
|
217 |
::new(place) T(value); |
|
218 |
}
|
|
219 |
||
220 |
static const T& GetValue(const wxAnyValueBuffer& buf) |
|
221 |
{
|
|
222 |
// Breaking this code into two lines should suppress
|
|
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; |
|
227 |
}
|
|
228 |
};
|
|
229 |
||
230 |
||
231 |
template<typename T> |
|
232 |
class wxAnyValueTypeOpsGeneric |
|
233 |
{
|
|
234 |
public: |
|
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 |
*/
|
|
280 |
template<typename T> |
|
281 |
class wxAnyValueTypeImplBase : public wxAnyValueType |
|
282 |
{
|
|
283 |
typedef typename wxIf< sizeof(T) <= WX_ANY_VALUE_BUFFER_SIZE, |
|
284 |
wxPrivate::wxAnyValueTypeOpsInplace<T>, |
|
285 |
wxPrivate::wxAnyValueTypeOpsGeneric<T> >::value |
|
286 |
Ops; |
|
287 |
||
288 |
public: |
|
289 |
wxAnyValueTypeImplBase() : wxAnyValueType() { } |
|
290 |
virtual ~wxAnyValueTypeImplBase() { } |
|
291 |
||
292 |
virtual void DeleteValue(wxAnyValueBuffer& buf) const |
|
293 |
{
|
|
294 |
Ops::DeleteValue(buf); |
|
295 |
}
|
|
296 |
||
297 |
virtual void CopyBuffer(const wxAnyValueBuffer& src, |
|
298 |
wxAnyValueBuffer& dst) const |
|
299 |
{
|
|
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 |
}
|
|
321 |
#if wxUSE_EXTENDED_RTTI
|
|
322 |
virtual const wxTypeInfo* GetTypeInfo() const |
|
323 |
{
|
|
324 |
return wxGetTypeInfo((T*)NULL); |
|
325 |
}
|
|
326 |
#endif
|
|
327 |
};
|
|
328 |
||
329 |
||
330 |
/*
|
|
331 |
Generic value type template. Note that bulk of the implementation
|
|
332 |
resides in wxAnyValueTypeImplBase.
|
|
333 |
*/
|
|
334 |
template<typename T> |
|
335 |
class wxAnyValueTypeImpl : public wxAnyValueTypeImplBase<T> |
|
336 |
{
|
|
337 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<T>) |
|
338 |
public: |
|
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 |
||
353 |
template<typename T> |
|
354 |
wxAnyValueTypeScopedPtr wxAnyValueTypeImpl<T>::sm_instance = new wxAnyValueTypeImpl<T>(); |
|
355 |
||
356 |
||
357 |
//
|
|
358 |
// Helper macro for using same base value type implementation for multiple
|
|
359 |
// actual C++ data types.
|
|
360 |
//
|
|
361 |
#define _WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
|
|
362 |
template<> \
|
|
363 |
class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##CLSTYPE \
|
|
364 |
{ \
|
|
365 |
typedef wxAnyBase##CLSTYPE##Type UseDataType; \
|
|
366 |
public: \
|
|
367 |
wxAnyValueTypeImpl() : wxAnyValueTypeImpl##CLSTYPE() { } \
|
|
368 |
virtual ~wxAnyValueTypeImpl() { } \
|
|
369 |
static void SetValue(const T& value, wxAnyValueBuffer& buf) \
|
|
370 |
{ \
|
|
371 |
void* voidPtr = reinterpret_cast<void*>(&buf.m_buffer[0]); \
|
|
372 |
UseDataType* dptr = reinterpret_cast<UseDataType*>(voidPtr); \
|
|
373 |
*dptr = static_cast<UseDataType>(value); \
|
|
374 |
} \
|
|
375 |
static T GetValue(const wxAnyValueBuffer& buf) \
|
|
376 |
{ \
|
|
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); \
|
|
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); \
|
|
390 |
} \
|
|
391 |
};
|
|
392 |
#else
|
|
393 |
#define WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE) \
|
|
394 |
_WX_ANY_DEFINE_SUB_TYPE(T, CLSTYPE)\
|
|
395 |
};
|
|
396 |
#endif
|
|
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 |
||
411 |
class WXDLLIMPEXP_BASE wxAnyValueTypeImplInt : |
|
412 |
public wxAnyValueTypeImplBase<wxAnyBaseIntType> |
|
413 |
{
|
|
414 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplInt) |
|
415 |
public: |
|
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 |
||
426 |
class WXDLLIMPEXP_BASE wxAnyValueTypeImplUint : |
|
427 |
public wxAnyValueTypeImplBase<wxAnyBaseUintType> |
|
428 |
{
|
|
429 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplUint) |
|
430 |
public: |
|
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 |
||
441 |
WX_ANY_DEFINE_SUB_TYPE(signed long, Int) |
|
442 |
WX_ANY_DEFINE_SUB_TYPE(signed int, Int) |
|
443 |
WX_ANY_DEFINE_SUB_TYPE(signed short, Int) |
|
444 |
WX_ANY_DEFINE_SUB_TYPE(signed char, Int) |
|
445 |
#ifdef wxLongLong_t
|
|
446 |
WX_ANY_DEFINE_SUB_TYPE(wxLongLong_t, Int) |
|
447 |
#endif
|
|
448 |
||
449 |
WX_ANY_DEFINE_SUB_TYPE(unsigned long, Uint) |
|
450 |
WX_ANY_DEFINE_SUB_TYPE(unsigned int, Uint) |
|
451 |
WX_ANY_DEFINE_SUB_TYPE(unsigned short, Uint) |
|
452 |
WX_ANY_DEFINE_SUB_TYPE(unsigned char, Uint) |
|
453 |
#ifdef wxLongLong_t
|
|
454 |
WX_ANY_DEFINE_SUB_TYPE(wxULongLong_t, Uint) |
|
455 |
#endif
|
|
456 |
||
457 |
||
458 |
//
|
|
459 |
// This macro is used in header, but then in source file we must have:
|
|
460 |
// WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME)
|
|
461 |
//
|
|
462 |
#define _WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, GV) \
|
|
463 |
class WXDLLIMPEXP_BASE wxAnyValueTypeImpl##TYPENAME : \
|
|
464 |
public wxAnyValueTypeImplBase<T> \
|
|
465 |
{ \
|
|
466 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl##TYPENAME) \
|
|
467 |
public: \
|
|
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 |
}; \
|
|
479 |
template<> \
|
|
480 |
class wxAnyValueTypeImpl<T> : public wxAnyValueTypeImpl##TYPENAME \
|
|
481 |
{ \
|
|
482 |
public: \
|
|
483 |
wxAnyValueTypeImpl() : wxAnyValueTypeImpl##TYPENAME() { } \
|
|
484 |
virtual ~wxAnyValueTypeImpl() { } \
|
|
485 |
};
|
|
486 |
||
487 |
#define WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
|
|
488 |
_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, CONVFUNC, BT) \
|
|
489 |
||
490 |
#define WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(T, TYPENAME, CONVFUNC) \
|
|
491 |
_WX_ANY_DEFINE_CONVERTIBLE_TYPE(T, TYPENAME, \
|
|
492 |
CONVFUNC, const T&) \
|
|
493 |
||
494 |
//
|
|
495 |
// String value type
|
|
496 |
//
|
|
497 |
||
498 |
// Convert wxString to destination wxAny value type
|
|
499 |
extern WXDLLIMPEXP_BASE bool wxAnyConvertString(const wxString& value, |
|
500 |
wxAnyValueType* dstType, |
|
501 |
wxAnyValueBuffer& dst); |
|
502 |
||
503 |
WX_ANY_DEFINE_CONVERTIBLE_TYPE_BASE(wxString, wxString, wxAnyConvertString) |
|
504 |
WX_ANY_DEFINE_CONVERTIBLE_TYPE(const char*, ConstCharPtr, |
|
505 |
wxAnyConvertString, wxString) |
|
506 |
WX_ANY_DEFINE_CONVERTIBLE_TYPE(const wchar_t*, ConstWchar_tPtr, |
|
507 |
wxAnyConvertString, wxString) |
|
508 |
||
509 |
//
|
|
510 |
// Bool value type
|
|
511 |
//
|
|
512 |
template<> |
|
513 |
class WXDLLIMPEXP_BASE wxAnyValueTypeImpl<bool> : |
|
514 |
public wxAnyValueTypeImplBase<bool> |
|
515 |
{
|
|
516 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>) |
|
517 |
public: |
|
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 |
//
|
|
530 |
class WXDLLIMPEXP_BASE wxAnyValueTypeImplDouble : |
|
531 |
public wxAnyValueTypeImplBase<double> |
|
532 |
{
|
|
533 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble) |
|
534 |
public: |
|
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
|
|
545 |
typedef double wxAnyBaseDoubleType; |
|
546 |
||
547 |
WX_ANY_DEFINE_SUB_TYPE(float, Double) |
|
548 |
WX_ANY_DEFINE_SUB_TYPE(double, Double) |
|
549 |
||
550 |
||
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) \
|
|
557 |
template<> \
|
|
558 |
class DECL wxAnyValueTypeImpl<CLS> : \
|
|
559 |
public wxAnyValueTypeImplBase<CLS> \
|
|
560 |
{ \
|
|
561 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<CLS>) \
|
|
562 |
public: \
|
|
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
|
|
583 |
// really test it properly in unit tests since a separate DLL would
|
|
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 |
||
597 |
#if wxUSE_VARIANT
|
|
598 |
||
599 |
class 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 |
||
609 |
class WXDLLIMPEXP_BASE wxAnyValueTypeImplVariantData : |
|
610 |
public wxAnyValueTypeImplBase<wxVariantData*> |
|
611 |
{
|
|
612 |
WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImplVariantData) |
|
613 |
public: |
|
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 |
||
657 |
template<> |
|
658 |
class wxAnyValueTypeImpl<wxVariantData*> : |
|
659 |
public wxAnyValueTypeImplVariantData |
|
660 |
{
|
|
661 |
public: |
|
662 |
wxAnyValueTypeImpl() : wxAnyValueTypeImplVariantData() { } |
|
663 |
virtual ~wxAnyValueTypeImpl() { } |
|
664 |
};
|
|
665 |
||
666 |
#endif // wxUSE_VARIANT |
|
667 |
||
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 |
*/
|
|
680 |
extern 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) \
|
|
687 |
bool 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 |
} \
|
|
697 |
bool 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 |
||
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.
|
|
715 |
extern WXDLLIMPEXP_BASE void |
|
716 |
wxPreRegisterAnyToVariant(wxAnyToVariantRegistration* reg); |
|
717 |
||
718 |
// This function performs main wxAny to wxVariant conversion duties.
|
|
719 |
extern WXDLLIMPEXP_BASE bool |
|
720 |
wxConvertAnyToVariant(const wxAny& any, wxVariant* variant); |
|
721 |
||
722 |
#endif // wxUSE_VARIANT |
|
723 |
||
724 |
||
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 |
//
|
|
732 |
class wxAny |
|
733 |
{
|
|
734 |
public: |
|
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 |
*/
|
|
755 |
template<typename T> |
|
756 |
wxAny(const T& value) |
|
757 |
{
|
|
758 |
m_type = wxAnyValueTypeImpl<T>::sm_instance.get(); |
|
759 |
wxAnyValueTypeImpl<T>::SetValue(value, m_buffer); |
|
760 |
}
|
|
761 |
||
762 |
// These two constructors are needed to deal with string literals
|
|
763 |
wxAny(const char* value) |
|
764 |
{
|
|
765 |
m_type = wxAnyValueTypeImpl<const char*>::sm_instance.get(); |
|
766 |
wxAnyValueTypeImpl<const char*>::SetValue(value, m_buffer); |
|
767 |
}
|
|
768 |
wxAny(const wchar_t* value) |
|
769 |
{
|
|
770 |
m_type = wxAnyValueTypeImpl<const wchar_t*>::sm_instance.get(); |
|
771 |
wxAnyValueTypeImpl<const wchar_t*>::SetValue(value, m_buffer); |
|
772 |
}
|
|
773 |
||
774 |
wxAny(const wxAny& any) |
|
775 |
{
|
|
776 |
m_type = wxAnyNullValueType; |
|
777 |
AssignAny(any); |
|
778 |
}
|
|
779 |
||
780 |
#if wxUSE_VARIANT
|
|
781 |
wxAny(const wxVariant& variant) |
|
782 |
{
|
|
783 |
m_type = wxAnyNullValueType; |
|
784 |
AssignVariant(variant); |
|
785 |
}
|
|
786 |
#endif
|
|
787 |
||
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> |
|
802 |
bool CheckType(T* = NULL) const |
|
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
|
|
812 |
of wxAny::GetType(). Instead, use wxAny::HasSameType().
|
|
813 |
||
814 |
@see HasSameType()
|
|
815 |
*/
|
|
816 |
const wxAnyValueType* GetType() const |
|
817 |
{
|
|
818 |
return m_type; |
|
819 |
}
|
|
820 |
||
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 |
||
830 |
/**
|
|
831 |
Tests if wxAny is null (that is, whether there is no data).
|
|
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 |
*/
|
|
851 |
template<typename T> |
|
852 |
wxAny& operator=(const T &value) |
|
853 |
{
|
|
854 |
m_type->DeleteValue(m_buffer); |
|
855 |
m_type = wxAnyValueTypeImpl<T>::sm_instance.get(); |
|
856 |
wxAnyValueTypeImpl<T>::SetValue(value, m_buffer); |
|
857 |
return *this; |
|
858 |
}
|
|
859 |
||
860 |
wxAny& operator=(const wxAny &any) |
|
861 |
{
|
|
862 |
if (this != &any) |
|
863 |
AssignAny(any); |
|
864 |
return *this; |
|
865 |
}
|
|
866 |
||
867 |
#if wxUSE_VARIANT
|
|
868 |
wxAny& operator=(const wxVariant &variant) |
|
869 |
{
|
|
870 |
AssignVariant(variant); |
|
871 |
return *this; |
|
872 |
}
|
|
873 |
#endif
|
|
874 |
||
875 |
// These two operators are needed to deal with string literals
|
|
876 |
wxAny& operator=(const char* value) |
|
877 |
{
|
|
878 |
Assign(value); |
|
879 |
return *this; |
|
880 |
}
|
|
881 |
wxAny& operator=(const wchar_t* value) |
|
882 |
{
|
|
883 |
Assign(value); |
|
884 |
return *this; |
|
885 |
}
|
|
886 |
||
887 |
//@{
|
|
888 |
/**
|
|
889 |
Equality operators.
|
|
890 |
*/
|
|
891 |
bool operator==(const wxString& value) const |
|
892 |
{
|
|
893 |
wxString value2; |
|
894 |
if ( !GetAs(&value2) ) |
|
895 |
return false; |
|
896 |
return value == value2; |
|
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 |
/**
|
|
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.
|
|
958 |
||
959 |
@remarks For convenience, conversion is done when T is wxString. This
|
|
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.
|
|
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) ) |
|
972 |
{
|
|
973 |
wxFAIL_MSG("Incorrect or non-convertible data type"); |
|
974 |
}
|
|
975 |
||
976 |
return static_cast<T>(wxAnyValueTypeImpl<T>::GetValue(m_buffer)); |
|
977 |
}
|
|
978 |
||
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 |
||
992 |
#if wxUSE_EXTENDED_RTTI
|
|
993 |
const wxTypeInfo* GetTypeInfo() const |
|
994 |
{
|
|
995 |
return m_type->GetTypeInfo(); |
|
996 |
}
|
|
997 |
#endif
|
|
998 |
/**
|
|
999 |
Template function that retrieves and converts the value of this
|
|
1000 |
variant to the type that T* value is.
|
|
1001 |
||
1002 |
@return Returns @true if conversion was successful.
|
|
1003 |
*/
|
|
1004 |
template<typename T> |
|
1005 |
bool GetAs(T* value) const |
|
1006 |
{
|
|
1007 |
if ( !wxAnyValueTypeImpl<T>::IsSameClass(m_type) ) |
|
1008 |
{
|
|
1009 |
wxAnyValueType* otherType = |
|
1010 |
wxAnyValueTypeImpl<T>::sm_instance.get(); |
|
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 |
||
1026 |
#if wxUSE_VARIANT
|
|
1027 |
// GetAs() wxVariant specialization
|
|
1028 |
bool GetAs(wxVariant* value) const |
|
1029 |
{
|
|
1030 |
return wxConvertAnyToVariant(*this, value); |
|
1031 |
}
|
|
1032 |
#endif
|
|
1033 |
||
1034 |
private: |
|
1035 |
// Assignment functions
|
|
1036 |
void AssignAny(const wxAny& any) |
|
1037 |
{
|
|
1038 |
// Must delete value - CopyBuffer() never does that
|
|
1039 |
m_type->DeleteValue(m_buffer); |
|
1040 |
||
1041 |
wxAnyValueType* newType = any.m_type; |
|
1042 |
||
1043 |
if ( !newType->IsSameType(m_type) ) |
|
1044 |
m_type = newType; |
|
1045 |
||
1046 |
newType->CopyBuffer(any.m_buffer, m_buffer); |
|
1047 |
}
|
|
1048 |
||
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
|
|
1067 |
m_type = wxAnyValueTypeImpl<wxVariantData*>::sm_instance.get(); |
|
1068 |
wxAnyValueTypeImpl<wxVariantData*>::SetValue(data, m_buffer); |
|
1069 |
}
|
|
1070 |
}
|
|
1071 |
#endif
|
|
1072 |
||
1073 |
template<typename T> |
|
1074 |
void Assign(const T &value) |
|
1075 |
{
|
|
1076 |
m_type->DeleteValue(m_buffer); |
|
1077 |
m_type = wxAnyValueTypeImpl<T>::sm_instance.get(); |
|
1078 |
wxAnyValueTypeImpl<T>::SetValue(value, m_buffer); |
|
1079 |
}
|
|
1080 |
||
1081 |
// Data
|
|
1082 |
wxAnyValueBuffer m_buffer; |
|
1083 |
wxAnyValueType* m_type; |
|
1084 |
};
|
|
1085 |
||
1086 |
||
1087 |
//
|
|
1088 |
// This method of checking the type is compatible with VC6
|
|
1089 |
#define wxANY_CHECK_TYPE(any, T) \
|
|
1090 |
wxANY_VALUE_TYPE_CHECK_TYPE((any).GetType(), T)
|
|
1091 |
||
1092 |
||
1093 |
//
|
|
1094 |
// This method of getting the value is compatible with VC6
|
|
1095 |
#define wxANY_AS(any, T) \
|
|
1096 |
(any).As(static_cast<T*>(NULL))
|
|
1097 |
||
1098 |
||
1099 |
template<typename T> |
|
1100 |
inline bool wxAnyValueType::CheckType(T* reserved) const |
|
1101 |
{
|
|
1102 |
wxUnusedVar(reserved); |
|
1103 |
return wxAnyValueTypeImpl<T>::IsSameClass(this); |
|
1104 |
}
|
|
1105 |
||
1106 |
WX_DECLARE_LIST_WITH_DECL(wxAny, wxAnyList, class WXDLLIMPEXP_BASE); |
|
1107 |
||
1108 |
#endif // wxUSE_ANY |
|
1109 |
||
1110 |
#endif // _WX_ANY_H_ |