File: any.h

package info (click to toggle)
wxwidgets3.0 3.0.5.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 120,464 kB
  • sloc: cpp: 896,633; makefile: 52,303; ansic: 21,971; sh: 5,713; python: 2,940; xml: 1,534; perl: 264; javascript: 33
file content (448 lines) | stat: -rw-r--r-- 13,863 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
/////////////////////////////////////////////////////////////////////////////
// Name:        any.h
// Purpose:     interface of wxAny
// Author:      wxWidgets team
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////


/**
    @class wxAny

    The wxAny class represents a container for any type. Its value
    can be changed at run time, possibly to a different type of value.

    wxAny is a backwards-incompatible (but convertible) successor class for
    wxVariant, essentially doing the same thing in a more modern, template-
    based manner and with transparent support for any user data type.

    Some pseudo-code'ish example of use with arbitrary user data:

    @code
    void SomeFunction()
    {
        MyClass myObject;
        wxAny any = myObject;

        // Do something
        // ...

        // Let's do a sanity check to make sure that any still holds
        // data of correct type.
        if ( any.CheckType<MyClass>() )
        {
            // Thank goodness, still a correct type.
            MyClass myObject2 = any.As<MyClass>();
        }
        else
        {
            // Something has gone horribly wrong!
            wxFAIL();
        }
    }
    @endcode

    When compared to wxVariant, there are various internal implementation
    differences as well. For instance, wxAny only allocates separate data
    object in heap for large objects (i.e. ones with size more than
    WX_ANY_VALUE_BUFFER_SIZE, which at the time of writing is 16 bytes).

    @note When performing conversions between strings and floating point
        numbers, the representation of numbers in C locale is always used.
        I.e. @code wxAny("1.23").GetAs<double>() @endcode will always work,
        even if the current locale uses comma as decimal separator.

    @library{wxbase}
    @category{data}

    @see wxAnyValueType, wxVariant, @ref overview_cpp_rtti_disabled
*/
class wxAny
{
public:
    /**
        Default constructor. It seeds the object with a null value.
    */
    wxAny();

    /**
        Constructs wxAny from data.
    */
    template<typename T>
    wxAny(const T& value);

    /**
        Constructs wxAny from another wxAny.
    */
    wxAny(const wxAny& any);

    /**
        Constructs wxAny, converting value from wxVariant.

        @remarks Because of this conversion, it is not usually possible to
                 have wxAny that actually holds a wxVariant. If wxVariant
                 cannot be converted to a specific data type, wxAny will then
                 hold and manage reference to wxVariantData* similar to how
                 wxVariant does.
    */
    wxAny(const wxVariant& variant);

    /**
        Destructor.
    */
    ~wxAny();

    /**
        This template function converts wxAny into given type. In most cases
        no type conversion is performed, so if the type is incorrect an
        assertion failure will occur.

        @remarks For conveniency, conversion is done when T is wxString. This
                 is useful when a string literal (which are treated as
                 const char* and const wchar_t*) has been assigned to wxAny.

                 This template function may not work properly with Visual C++
                 6. For full compiler compatibility, please use
                 wxANY_AS(any, T) macro instead.
    */
    template<typename T>
    T As() const;

    /**
        Use this template function for checking if this wxAny holds
        a specific C++ data type.

        @remarks This template function may not work properly with Visual C++
                6. For full compiler compatibility, please use
                wxANY_CHECK_TYPE(any, T) macro instead.

        @see wxAnyValueType::CheckType()
    */
    template<typename T>
    bool CheckType() const;

    /**
        Template function that retrieves and converts the value of this
        wxAny to the type that T* value is.

        @return Returns @true if conversion was successful.
    */
    template<typename T>
    bool GetAs(T* value) const;

    /**
        Specialization of GetAs() that allows conversion of wxAny into
        wxVariant.

        @return Returns @true if conversion was successful. Conversion usually
                only fails if variant used custom wxVariantData that did not
                implement the wxAny to wxVariant conversion functions.
    */
    bool GetAs(wxVariant* value) const;

    /**
        Returns the value type as wxAnyValueType instance.

        @remarks You cannot reliably test whether two wxAnys are of
                 same value type by simply comparing return values
                 of wxAny::GetType(). Instead, use wxAny::HasSameType().

        @see HasSameType()
    */
    const wxAnyValueType* GetType() const;

    /**
        Returns @true if this and another wxAny have the same
        value type.
    */
    bool HasSameType(const wxAny& other) const;

    /**
        Tests if wxAny is null (that is, whether there is no data).
    */
    bool IsNull() const;

    /**
        Makes wxAny null (that is, clears it).
    */
    void MakeNull();

    //@{
    /**
        @name Assignment operators
    */
    template<typename T>
    wxAny& operator=(const T &value);
    wxAny& operator=(const wxAny &any);
    wxAny& operator=(const wxVariant &variant);
    //@}

    //@{
    /**
        @name Equality operators

        @remarks Generic template-based comparison operators have not been
                provided for various code consistency reasons, so for custom
                data types you have do something like this:

                @code
                if ( any.CheckType<MyClass*>() &&
                     any.As<MyClass*>() == myObjectPtr )
                {
                    // Do something if any stores myObjectPtr
                }
                @endcode
    */
    bool operator==(signed char value) const;
    bool operator==(signed short value) const;
    bool operator==(signed int value) const;
    bool operator==(signed long value) const;
    bool operator==(wxLongLong_t value) const;
    bool operator==(unsigned char value) const;
    bool operator==(unsigned short value) const;
    bool operator==(unsigned int value) const;
    bool operator==(unsigned long value) const;
    bool operator==(wxULongLong_t value) const;
    bool operator==(float value) const;
    bool operator==(double value) const;
    bool operator==(bool value) const;
    bool operator==(const char* value) const;
    bool operator==(const wchar_t* value) const;
    bool operator==(const wxString& value) const;
    //@}

    //@{
    /**
        @name Inequality operators
    */
    bool operator!=(signed char value) const;
    bool operator!=(signed short value) const;
    bool operator!=(signed int value) const;
    bool operator!=(signed long value) const;
    bool operator!=(wxLongLong_t value) const;
    bool operator!=(unsigned char value) const;
    bool operator!=(unsigned short value) const;
    bool operator!=(unsigned int value) const;
    bool operator!=(unsigned long value) const;
    bool operator!=(wxULongLong_t value) const;
    bool operator!=(float value) const;
    bool operator!=(double value) const;
    bool operator!=(bool value) const;
    bool operator!=(const char* value) const;
    bool operator!=(const wchar_t* value) const;
    bool operator!=(const wxString& value) const;
    //@}
};

/**
    This is value getter macro that is more compatible with older
    compilers, such as Visual C++ 6.0.
*/
#define wxANY_AS(any, T)


/**
    This is type checking macro that is more compatible with older
    compilers, such as Visual C++ 6.0.
*/
#define wxANY_CHECK_TYPE(any, T)


/**
    Size of the wxAny value buffer.
*/
enum
{
    WX_ANY_VALUE_BUFFER_SIZE = 16
};

/**
    Type for buffer within wxAny for holding data.
*/
union wxAnyValueBuffer
{
    void*   m_ptr;
    wxByte  m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
};


/**
    @class wxAnyValueType

    wxAnyValueType is base class for value type functionality for C++ data
    types used with wxAny. Usually the default template will create a
    satisfactory wxAnyValueType implementation for a data type, but
    sometimes you may need to add some customization. To do this you will need
    to add specialized template of wxAnyValueTypeImpl<>. Often your only
    need may be to add dynamic type conversion which would be done like
    this:

    @code
        template<>
        class wxAnyValueTypeImpl<MyClass> :
            public wxAnyValueTypeImplBase<MyClass>
        {
            WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
        public:
            wxAnyValueTypeImpl() :
                wxAnyValueTypeImplBase<MyClass>() { }
            virtual ~wxAnyValueTypeImpl() { }

            virtual bool ConvertValue(const wxAnyValueBuffer& src,
                                      wxAnyValueType* dstType,
                                      wxAnyValueBuffer& dst) const
            {
                // GetValue() is a static member function implemented
                // in wxAnyValueTypeImplBase<>.
                MyClass value = GetValue(src);

                // TODO: Convert value from src buffer to destination
                //       type and buffer. If cannot be done, return
                //       false. This is a simple sample.
                if ( dstType->CheckType<wxString>() )
                {
                    wxString s = value.ToString();
                    wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
                }
                else
                {
                    return false;
                }
            }
        };

        //
        // Following must be placed somewhere in your source code
        WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
    @endcode

    wxAnyValueTypeImplBase<> template, from which we inherit in the above
    example, contains the bulk of the default wxAnyValueTypeImpl<> template
    implementation, and as such allows you to easily add some minor
    customization.

    If you need a have complete control over the type interpretation, you
    will need to derive a class directly from wxAnyValueType, like this:

    @code
        template <>
        class wxAnyValueTypeImpl<MyClass> : public wxAnyValueType
        {
            WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
        public:
            virtual void DeleteValue(wxAnyValueBuffer& buf) const
            {
                // TODO: Free the data in buffer
                // It is important to clear the buffer like this
                // at the end of DeleteValue().
                buf.m_ptr = NULL;
            }

            virtual void CopyBuffer(const wxAnyValueBuffer& src,
                                    wxAnyValueBuffer& dst) const
            {
                // TODO: Copy value from one buffer to another.
                //       dst is already uninitialized and does not
                //       need to be freed.
            }

            virtual bool ConvertValue(const wxAnyValueBuffer& src,
                                      wxAnyValueType* dstType,
                                      wxAnyValueBuffer& dst) const
            {
                // TODO: Convert value from src buffer to destination
                //       type and buffer.
            }

            //
            // Following static functions must be implemented
            //

            static void SetValue(const T& value,
                                 wxAnyValueBuffer& buf)
            {
                // TODO: Store value into buf.
            }

            static const T& GetValue(const wxAnyValueBuffer& buf)
            {
                // TODO: Return reference to value stored in buffer.
            }
        };

        //
        // Following must be placed somewhere in your source code
        WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)

    @endcode

    @library{wxbase}
    @category{data}

    @see wxAny
*/
class wxAnyValueType
{
public:
    /**
        Default constructor.
    */
    wxAnyValueType();

    /**
        Destructor.
    */
    virtual ~wxAnyValueType();

    /**
        Use this template function for checking if wxAnyValueType represents
        a specific C++ data type.

        @remarks This template function does not work on some older compilers
                (such as Visual C++ 6.0). For full compiler compatibility
                please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
                instead.

        @see wxAny::CheckType()
    */
    template <typename T>
    bool CheckType() const;

    /**
        Convert value into buffer of different type. Return false if
        not possible.
    */
    virtual bool ConvertValue(const wxAnyValueBuffer& src,
                              wxAnyValueType* dstType,
                              wxAnyValueBuffer& dst) const = 0;

    /**
        Implement this for buffer-to-buffer copy.

        @param src
            This is the source data buffer.

        @param dst
            This is the destination data buffer that is in either
            uninitialized or freed state.
    */
    virtual void CopyBuffer(const wxAnyValueBuffer& src,
                            wxAnyValueBuffer& dst) const = 0;

    /**
        This function is called every time the data in wxAny
        buffer needs to be freed.
    */
    virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;

    /**
        This function is used for internal type matching.
    */
    virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
};

/**
    This is type checking macro that is more compatible with older
    compilers, such as Visual C++ 6.0.
*/
#define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T)