~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to include/wx/any.h

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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_