summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qvariant.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qvariant.h')
-rw-r--r--src/corelib/kernel/qvariant.h74
1 files changed, 63 insertions, 11 deletions
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 07ef4dc41e..089d0d643b 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -49,6 +49,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
+#include <QtCore/qobject.h>
QT_BEGIN_HEADER
@@ -88,6 +89,39 @@ inline QVariant qVariantFromValue(const T &);
template<typename T>
inline T qvariant_cast(const QVariant &);
+namespace QtPrivate {
+
+ template <typename Derived, typename Argument, typename ReturnType>
+ struct ObjectInvoker
+ {
+ static ReturnType invoke(Argument a)
+ {
+ return Derived::object(a);
+ }
+ };
+
+ template <typename Derived, typename Argument, typename ReturnType>
+ struct MetaTypeInvoker
+ {
+ static ReturnType invoke(Argument a)
+ {
+ return Derived::metaType(a);
+ }
+ };
+
+ template <typename Derived, typename T, typename Argument, typename ReturnType, bool = IsPointerToTypeDerivedFromQObject<T>::Value>
+ struct TreatAsQObjectBeforeMetaType : ObjectInvoker<Derived, Argument, ReturnType>
+ {
+ };
+
+ template <typename Derived, typename T, typename Argument, typename ReturnType>
+ struct TreatAsQObjectBeforeMetaType<Derived, T, Argument, ReturnType, false> : MetaTypeInvoker<Derived, Argument, ReturnType>
+ {
+ };
+
+ template<typename T> struct QVariantValueHelper;
+}
+
class Q_CORE_EXPORT QVariant
{
public:
@@ -153,7 +187,7 @@ class Q_CORE_EXPORT QVariant
Icon = QMetaType::QIcon,
SizePolicy = QMetaType::QSizePolicy,
- UserType = 127,
+ UserType = QMetaType::User,
LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
};
@@ -375,14 +409,15 @@ protected:
#ifndef QT_NO_DEBUG_STREAM
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
#endif
- Private d;
#ifndef Q_NO_TEMPLATE_FRIENDS
template<typename T>
friend inline T qvariant_cast(const QVariant &);
+ template<typename T> friend struct QtPrivate::QVariantValueHelper;
protected:
#else
public:
#endif
+ Private d;
void create(int type, const void *copy);
bool cmp(const QVariant &other) const;
bool convert(const int t, void *ptr) const;
@@ -481,18 +516,35 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
}
#endif
+namespace QtPrivate {
+ template<typename T>
+ struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T>
+ {
+ static T metaType(const QVariant &v)
+ {
+ const int vid = qMetaTypeId<T>(static_cast<T *>(0));
+ if (vid == v.userType())
+ return *reinterpret_cast<const T *>(v.constData());
+ if (vid < int(QMetaType::User)) {
+ T t;
+ if (v.convert(QVariant::Type(vid), &t))
+ return t;
+ }
+ return T();
+ }
+#ifndef QT_NO_QOBJECT
+ static T object(const QVariant &v)
+ {
+ return qobject_cast<T>(QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject ? v.d.data.o : 0);
+ }
+#endif
+ };
+}
+
#ifndef QT_MOC
template<typename T> inline T qvariant_cast(const QVariant &v)
{
- const int vid = qMetaTypeId<T>(static_cast<T *>(0));
- if (vid == v.userType())
- return *reinterpret_cast<const T *>(v.constData());
- if (vid < int(QMetaType::User)) {
- T t;
- if (v.convert(vid, &t))
- return t;
- }
- return T();
+ return QtPrivate::QVariantValueHelper<T>::invoke(v);
}
template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)