~ubuntu-branches/ubuntu/saucy/qt-gstreamer/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/boost1.48.patch/src/QGlib/value.h

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2012-06-15 15:03:26 UTC
  • mfrom: (1.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20120615150326-pkmdog620pkytcgt
Tags: 0.10.2-2ubuntu1
* Merge from Debian unstable, remaining changes:
  - Enable unit tests.
    + Build-depend on gstreamer0.10-plugins-base.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    Copyright (C) 2009-2010  George Kiagiadakis <kiagiadakis.george@gmail.com>
3
 
    Copyright (C) 2010 Collabora Ltd.
4
 
      @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
5
 
 
6
 
    This library is free software; you can redistribute it and/or modify
7
 
    it under the terms of the GNU Lesser General Public License as published
8
 
    by the Free Software Foundation; either version 2.1 of the License, or
9
 
    (at your option) any later version.
10
 
 
11
 
    This program is distributed in the hope that it will be useful,
12
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
    GNU General Public License for more details.
15
 
 
16
 
    You should have received a copy of the GNU Lesser General Public License
17
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
#ifndef QGLIB_VALUE_H
20
 
#define QGLIB_VALUE_H
21
 
 
22
 
#include "global.h"
23
 
#include "type.h"
24
 
#include "refpointer.h"
25
 
#include <boost/mpl/if.hpp>
26
 
#include <boost/type_traits.hpp>
27
 
#include <stdexcept>
28
 
#include <QtCore/QString>
29
 
#include <QtCore/QDebug>
30
 
#include <QtCore/QSharedData>
31
 
 
32
 
namespace QGlib {
33
 
 
34
 
/*! This structure holds the set and get methods that are used internally
35
 
 * by Value to handle data of a specific type. If you want to provide
36
 
 * support for a custom type, you need to write two such methods, create
37
 
 * a new ValueVTable instance that holds pointers to them and register it
38
 
 * using Value::registerValueVTable().
39
 
 * \sa \ref value_design
40
 
 */
41
 
struct QTGLIB_EXPORT ValueVTable
42
 
{
43
 
    typedef void (*SetFunction)(Value & value, const void *data);
44
 
    typedef void (*GetFunction)(const Value & value, void *data);
45
 
 
46
 
    inline ValueVTable() : set(NULL), get(NULL) {}
47
 
    inline ValueVTable(SetFunction s, GetFunction g) : set(s), get(g) {}
48
 
 
49
 
    SetFunction set;
50
 
    GetFunction get;
51
 
};
52
 
 
53
 
 
54
 
/*! \headerfile value.h <QGlib/Value>
55
 
 * \brief Wrapper class for GValue
56
 
 *
57
 
 * This class serves as a wrapper for GValue. GValue is a data type that can hold different
58
 
 * types of values inside, like a QVariant.
59
 
 *
60
 
 * A Value object holds a single value of a single type() at a time. To create a new Value,
61
 
 * use the static create() method or one of the constructors. To get the held value, use
62
 
 * the template get() method or one of the toT() functions (ex. toInt()).
63
 
 *
64
 
 * To set a value to an invalid Value (on which isValid() returns false), you must first
65
 
 * initialize this Value using one of the init() methods (preferably the template one) in order
66
 
 * to tell it what kind of value it is going to hold. Once initialized to hold a specific type,
67
 
 * you can use the set() method to set a value. To change the type that this value holds, you
68
 
 * can call the init() method again at any time. In this case, though, any previously held value
69
 
 * will be lost.
70
 
 *
71
 
 * \note This class is implicitly shared.
72
 
 */
73
 
class QTGLIB_EXPORT Value
74
 
{
75
 
public:
76
 
    /*! Creates a new invalid Value \sa isValid() */
77
 
    Value();
78
 
 
79
 
    /*! Creates a new Value that holds a copy of the given \a gvalue */
80
 
    explicit Value(const GValue *gvalue);
81
 
 
82
 
    /*! Creates a new Value and initializes it to hold values of the given \a type.
83
 
     * This is equivalent to:
84
 
     * \code
85
 
     * Value v;
86
 
     * v.init(type);
87
 
     * \endcode
88
 
     */
89
 
    explicit Value(Type type);
90
 
 
91
 
    Value(bool val); ///< Creates a new Value of Type::Bool and sets it to hold \a val
92
 
    Value(char val); ///< Creates a new Value of Type::Char and sets it to hold \a val
93
 
    Value(uchar val); ///< Creates a new Value of Type::Uchar and sets it to hold \a val
94
 
    Value(int val); ///< Creates a new Value of Type::Int and sets it to hold \a val
95
 
    Value(uint val); ///< Creates a new Value of Type::Uint and sets it to hold \a val
96
 
    Value(long val); ///< Creates a new Value of Type::Long and sets it to hold \a val
97
 
    Value(ulong val); ///< Creates a new Value of Type::Ulong and sets it to hold \a val
98
 
    Value(qint64 val); ///< Creates a new Value of Type::Int64 and sets it to hold \a val
99
 
    Value(quint64 val); ///< Creates a new Value of Type::Uint64 and sets it to hold \a val
100
 
    Value(float val); ///< Creates a new Value of Type::Float and sets it to hold \a val
101
 
    Value(double val); ///< Creates a new Value of Type::Double and sets it to hold \a val
102
 
    Value(const char *val); ///< Creates a new Value of Type::String and sets it to hold \a val
103
 
    Value(const QByteArray & val); ///< Creates a new Value of Type::String and sets it to hold \a val
104
 
    Value(const QString & val); ///< Creates a new Value of Type::String and sets it to hold \a val
105
 
 
106
 
    Value(const Value & other);
107
 
    Value & operator=(const Value & other);
108
 
 
109
 
    virtual ~Value();
110
 
 
111
 
 
112
 
    /*! Creates a new Value that is intialized to hold data
113
 
     * of type T and sets it to hold \a data.
114
 
     * \note T must be a type registered with the QtGLib type system. Attempting
115
 
     * to use a type that is not properly registered will fail to compile.
116
 
     */
117
 
    template <typename T>
118
 
    static inline Value create(const T & data);
119
 
 
120
 
 
121
 
    /*! Initializes or re-initializes this Value to hold data of the given \a type.
122
 
     * If this Value was previously holding any data, this data will be freed.
123
 
     */
124
 
    void init(Type type);
125
 
 
126
 
    /*! Initializes or re-initializes this Value to hold data of type T.
127
 
     * If this Value was previously holding any data, this data will be freed.
128
 
     * \note T must be a type registered with the QtGLib type system. Attempting
129
 
     * to use a type that is not properly registered will fail to compile.
130
 
     */
131
 
    template <typename T>
132
 
    inline void init();
133
 
 
134
 
 
135
 
    /*! \returns whether this Value instance is initialized to hold a certain type
136
 
     * \sa init() */
137
 
    bool isValid() const;
138
 
 
139
 
    /*! \returns the type that this Value instance has been initialized to hold */
140
 
    Type type() const;
141
 
 
142
 
    /*! \returns whether it is possible to transform this Value to a Value of another type */
143
 
    bool canTransformTo(Type type) const;
144
 
 
145
 
    /*! Transforms the current value into a value of the specified \a type, if possible.
146
 
     * Possible transformations are, for example, int to float, int to string, etc...
147
 
     * The original Value remains unaffected and the transformed Value is returned.
148
 
    */
149
 
    Value transformTo(Type type) const;
150
 
 
151
 
    /*! Clears the current value in this Value instance and resets it to the
152
 
     * default value (as if the Value had just been initialized). */
153
 
    void clear();
154
 
 
155
 
 
156
 
    /*! Retrieves the value stored in this Value instance, as the specified type T.
157
 
     * The bindings take care of calling the appropriate g_value_get_* method depending
158
 
     * on the type T. Note though that this is only meant to be used with the types of
159
 
     * the bindings, not their C types. This means that if for example the Value has
160
 
     * been initialized to hold a GstObject pointer, you can use:
161
 
     * \code
162
 
     * QGst::ObjectPtr object = value.get<QGst::ObjectPtr>();
163
 
     * \endcode
164
 
     * but \em not this:
165
 
     * \code
166
 
     * GstObject *object = value.get<GstObject*>(); //will cause compilation error
167
 
     * \endcode
168
 
     *
169
 
     * If the underlying stored value is not of the type T, this method will attempt
170
 
     * to convert it to type T. If this is not possible, a default constructed value
171
 
     * will be returned.
172
 
     *
173
 
     * If \a ok has been specified, it is set to true if the value was retrieved
174
 
     * successfully or false if there was an error (probably conversion error) and
175
 
     * a default constructed value has been returned.
176
 
     */
177
 
    template <typename T> T get(bool *ok = NULL) const;
178
 
 
179
 
    /*! Sets this Value instance to hold the specified \a data.
180
 
     * As with get(), the bindings take care of calling the appropriate g_value_set_*
181
 
     * method depending on the type T, but note that this is only meant to be used
182
 
     * with the types of the bindings.
183
 
     *
184
 
     * If this Value instance has been initialized to hold a different type of data
185
 
     * than T, a conversion to the correct type() will be attempted. If the conversion
186
 
     * fails, the Value will remain unaffected and a warning will be printed.
187
 
     * \sa get()
188
 
     */
189
 
    template <typename T> void set(const T & data);
190
 
 
191
 
 
192
 
    /*! Returns the held value as a bool. Equivalent to get<bool>(ok); \sa get() */
193
 
    inline bool toBool(bool *ok = NULL) const { return get<bool>(ok); }
194
 
 
195
 
    /*! Returns the held value as a char. Equivalent to get<char>(ok); \sa get() */
196
 
    inline char toChar(bool *ok = NULL) const { return get<char>(ok); }
197
 
 
198
 
    /*! Returns the held value as a uchar. Equivalent to get<uchar>(ok); \sa get() */
199
 
    inline uchar toUChar(bool *ok = NULL) const { return get<uchar>(ok); }
200
 
 
201
 
    /*! Returns the held value as an int. Equivalent to get<int>(ok); \sa get() */
202
 
    inline int toInt(bool *ok = NULL) const { return get<int>(ok); }
203
 
 
204
 
    /*! Returns the held value as a uint. Equivalent to get<uint>(ok); \sa get() */
205
 
    inline uint toUInt(bool *ok = NULL) const { return get<uint>(ok); }
206
 
 
207
 
    /*! Returns the held value as a long. Equivalent to get<long>(ok); \sa get() */
208
 
    inline long toLong(bool *ok = NULL) const { return get<long>(ok); }
209
 
 
210
 
    /*! Returns the held value as a ulong. Equivalent to get<ulong>(ok); \sa get() */
211
 
    inline ulong toULong(bool *ok = NULL) const { return get<ulong>(ok); }
212
 
 
213
 
    /*! Returns the held value as a qint64. Equivalent to get<qint64>(ok); \sa get() */
214
 
    inline qint64 toInt64(bool *ok = NULL) const { return get<qint64>(ok); }
215
 
 
216
 
    /*! Returns the held value as a quint64. Equivalent to get<quint64>(ok); \sa get() */
217
 
    inline quint64 toUInt64(bool *ok = NULL) const { return get<quint64>(ok); }
218
 
 
219
 
    /*! Returns the held value as a QByteAray. Equivalent to get<QByteArray>(ok); \sa get() */
220
 
    inline QByteArray toByteArray(bool *ok = NULL) const { return get<QByteArray>(ok); }
221
 
 
222
 
    /*! Returns the held value as a QString. Equivalent to get<QString>(ok); \sa get() */
223
 
    inline QString toString(bool *ok = NULL) const { return get<QString>(ok); }
224
 
 
225
 
 
226
 
    /*! This is a cast operator that gives access to the underlying GValue instance.
227
 
     * It is provided for convenience, to be able to pass this Value as argument to C
228
 
     * functions that expect a GValue pointer. Use this feature with care. Do not store
229
 
     * the pointer, as it may go away at any time. This Value instance keeps control of
230
 
     * this pointer. If you need to store it, use g_value_copy() to copy it first.
231
 
     */
232
 
    operator GValue*();
233
 
    operator const GValue*() const; ///< \overload
234
 
 
235
 
 
236
 
    /*! Registers the given ValueVTable \a vtable for the given \a type.
237
 
     * This is provided to let you add support for a custom type, if necessary.
238
 
     * You should normally not need to do that, as most types are handled
239
 
     * by the handlers of their parent types.
240
 
     * \sa \ref value_design
241
 
     */
242
 
    static void registerValueVTable(Type type, const ValueVTable & vtable);
243
 
 
244
 
private:
245
 
    template <typename T>
246
 
    friend struct ValueImpl;
247
 
 
248
 
    /*! Retrieves the data from this Value and places it into the memory position
249
 
     * pointed to by \a data. \a dataType indicates the actual data type of \a data
250
 
     * and is used, among others, to cast \a data back to the actual C++ type that
251
 
     * it points to and assign it.
252
 
     * \note This method should only be accessed from ValueImpl.
253
 
     * \sa \ref value_design
254
 
     */
255
 
    void getData(Type dataType, void *data) const;
256
 
 
257
 
    /*! Sets the data of this Value to be the data pointed to by \a data.
258
 
     * \a dataType indicates the actual data type of \a data and is used,
259
 
     * among others, to cast \a data back to the actual C++ type that
260
 
     * it points to and retrieve its value.
261
 
     * \note This method should only be accessed from ValueImpl.
262
 
     * \sa \ref value_design
263
 
     */
264
 
    void setData(Type dataType, const void *data);
265
 
 
266
 
    struct Data;
267
 
    QSharedDataPointer<Data> d;
268
 
};
269
 
 
270
 
 
271
 
/*! This struct provides the implementation for the Value::get() and Value::set() methods.
272
 
 * If you want to provide support for a custom type, you may want to provide a template
273
 
 * specialization of this class to handle your type in a different way than the default
274
 
 * implementation. You should normally not need to be concerned at all with this.
275
 
 * \note this struct is declared as friend in Value and as a result it has access to
276
 
 * Value::setData() and Value::getData()
277
 
 * \sa \ref value_design
278
 
 */
279
 
template <typename T>
280
 
struct ValueImpl
281
 
{
282
 
    static inline T get(const Value & value);
283
 
    static inline void set(Value & value, const T & data);
284
 
};
285
 
 
286
 
// -- template implementations --
287
 
 
288
 
//static
289
 
template <typename T>
290
 
inline Value Value::create(const T & data)
291
 
{
292
 
    Value v;
293
 
    v.init<T>();
294
 
    v.set(data);
295
 
    return v;
296
 
}
297
 
 
298
 
template <typename T>
299
 
inline void Value::init()
300
 
{
301
 
    init(GetType<T>());
302
 
}
303
 
 
304
 
template <typename T>
305
 
T Value::get(bool *ok) const
306
 
{
307
 
    if (ok) {
308
 
        *ok = true;
309
 
    }
310
 
 
311
 
    try {
312
 
        return ValueImpl<T>::get(*this);
313
 
    } catch (const std::exception &) {
314
 
        if (ok) {
315
 
            *ok = false;
316
 
        }
317
 
        return T();
318
 
    }
319
 
}
320
 
 
321
 
template <typename T>
322
 
void Value::set(const T & data)
323
 
{
324
 
    try {
325
 
        ValueImpl<T>::set(*this, data);
326
 
    } catch (const std::exception & e) {
327
 
        qWarning() << "QGlib::Value::set:" << e.what();
328
 
    }
329
 
}
330
 
 
331
 
// -- default ValueImpl implementation --
332
 
 
333
 
template <typename T>
334
 
inline T ValueImpl<T>::get(const Value & value)
335
 
{
336
 
    //Use int for enums, T for everything else
337
 
    typename boost::mpl::if_<
338
 
        boost::is_enum<T>,
339
 
        int, T
340
 
    >::type result;
341
 
 
342
 
    value.getData(GetType<T>(), &result);
343
 
    return static_cast<T>(result);
344
 
}
345
 
 
346
 
template <typename T>
347
 
inline void ValueImpl<T>::set(Value & value, const T & data)
348
 
{
349
 
    //Use const int for enums, const T for everything else
350
 
    typename boost::mpl::if_<
351
 
        boost::is_enum<T>,
352
 
        const int, const T &
353
 
    >::type dataRef = data;
354
 
 
355
 
    value.setData(GetType<T>(), &dataRef);
356
 
}
357
 
 
358
 
// -- ValueImpl specialization for QFlags --
359
 
 
360
 
template <class T>
361
 
struct ValueImpl< QFlags<T> >
362
 
{
363
 
    static inline QFlags<T> get(const Value & value)
364
 
    {
365
 
        uint flags;
366
 
        value.getData(GetType< QFlags<T> >(), &flags);
367
 
        return QFlags<T>(QFlag(flags));
368
 
    }
369
 
 
370
 
    static inline void set(Value & value, const QFlags<T> & data)
371
 
    {
372
 
        uint flags = data;
373
 
        value.setData(GetType< QFlags<T> >(), &flags);
374
 
    }
375
 
};
376
 
 
377
 
// -- ValueImpl specialization for RefPointer --
378
 
 
379
 
template <class T>
380
 
struct ValueImpl< RefPointer<T> >
381
 
{
382
 
    static inline RefPointer<T> get(const Value & value)
383
 
    {
384
 
        typename T::CType *gobj;
385
 
        value.getData(GetType<T>(), &gobj);
386
 
        return RefPointer<T>::wrap(gobj);
387
 
    }
388
 
 
389
 
    static inline void set(Value & value, const RefPointer<T> & data)
390
 
    {
391
 
        typename T::CType *gobj = static_cast<typename T::CType*>(data);
392
 
        value.setData(GetType<T>(), &gobj);
393
 
    }
394
 
};
395
 
 
396
 
// -- ValueImpl specializations for string literals --
397
 
 
398
 
template <int N>
399
 
struct ValueImpl<const char[N]> //ISO C++ string literals are const char[]
400
 
{
401
 
    //No get method, obviously.
402
 
 
403
 
    static inline void set(Value & value, const char (&data)[N])
404
 
    {
405
 
        QByteArray str = QByteArray::fromRawData(data, N);
406
 
        value.setData(Type::String, &str);
407
 
    }
408
 
};
409
 
 
410
 
template <int N>
411
 
struct ValueImpl<char[N]> //gcc string literals are char[]
412
 
{
413
 
    //No get method, obviously.
414
 
 
415
 
    static inline void set(Value & value, const char (&data)[N])
416
 
    {
417
 
        QByteArray str = QByteArray::fromRawData(data, N);
418
 
        value.setData(Type::String, &str);
419
 
    }
420
 
};
421
 
 
422
 
// -- ValueImpl specialization for const char* --
423
 
 
424
 
template <>
425
 
struct ValueImpl<const char*>
426
 
{
427
 
    //No get method, obviously.
428
 
 
429
 
    static inline void set(Value & value, const char *data)
430
 
    {
431
 
        QByteArray str = QByteArray::fromRawData(data, qstrlen(data));
432
 
        value.setData(Type::String, &str);
433
 
    }
434
 
};
435
 
 
436
 
// -- ValueImpl specialization for QString --
437
 
 
438
 
template <>
439
 
struct ValueImpl<QString>
440
 
{
441
 
    static inline QString get(const Value & value)
442
 
    {
443
 
        QByteArray str;
444
 
        value.getData(Type::String, &str);
445
 
        return QString::fromUtf8(str);
446
 
    }
447
 
 
448
 
    static inline void set(Value & value, const QString & data)
449
 
    {
450
 
        QByteArray str = data.toUtf8();
451
 
        value.setData(Type::String, &str);
452
 
    }
453
 
};
454
 
 
455
 
// -- ValueImpl specialization for Value --
456
 
 
457
 
template <>
458
 
struct ValueImpl<Value>
459
 
{
460
 
    static inline Value get(const Value & value)
461
 
    {
462
 
        return value;
463
 
    }
464
 
 
465
 
    static inline void set(Value & value, const Value & data)
466
 
    {
467
 
        value = data;
468
 
    }
469
 
};
470
 
 
471
 
// -- Exceptions thrown from getData/setData --
472
 
 
473
 
namespace Private {
474
 
 
475
 
class QTGLIB_EXPORT InvalidValueException : public std::logic_error
476
 
{
477
 
public:
478
 
    inline InvalidValueException()
479
 
        : std::logic_error("This Value instance has not been initialized") {}
480
 
};
481
 
 
482
 
class QTGLIB_EXPORT InvalidTypeException : public std::logic_error
483
 
{
484
 
public:
485
 
    inline InvalidTypeException(const std::string & dataType, const std::string & valueType)
486
 
        : std::logic_error("Unable to handle value type \"" + dataType +
487
 
                           "\". This Value instance has been initialized to hold values of type \""
488
 
                           + valueType + "\" and no conversion is possible") {}
489
 
};
490
 
 
491
 
class QTGLIB_EXPORT UnregisteredTypeException : public std::logic_error
492
 
{
493
 
public:
494
 
    inline UnregisteredTypeException(const std::string & typeName)
495
 
        : std::logic_error("Unable to handle unregistered type \"" + typeName + "\"") {}
496
 
};
497
 
 
498
 
class QTGLIB_EXPORT TransformationFailedException : public std::runtime_error
499
 
{
500
 
public:
501
 
    inline TransformationFailedException(const std::string & srcTypeName,
502
 
                                         const std::string & destTypeName)
503
 
        : std::runtime_error("Failed to transform value from type \""
504
 
                             + srcTypeName + "\" to type \"" + destTypeName + "\"") {}
505
 
};
506
 
 
507
 
} //namespace Private
508
 
 
509
 
// -- QDebug operator --
510
 
 
511
 
/*! \relates QGlib::Value */
512
 
QTGLIB_EXPORT QDebug operator<<(QDebug debug, const Value & value);
513
 
 
514
 
} //namespace QGlib
515
 
 
516
 
QGLIB_REGISTER_TYPE(QGlib::Value)
517
 
 
518
 
#endif