summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r--src/corelib/kernel/qmetatype.h117
1 files changed, 78 insertions, 39 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index ec9a256c4d..1e944660c6 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -18,6 +18,7 @@
#include <QtCore/qobjectdefs.h>
#endif
#include <QtCore/qscopeguard.h>
+#include <QtCore/qttypetraits.h>
#include <array>
#include <new>
@@ -26,7 +27,7 @@
#include <map>
#include <functional>
#include <optional>
-#include <type_traits>
+#include <QtCore/q20type_traits.h>
#ifdef Bool
#error qmetatype.h must be included before any header file that defines Bool
@@ -92,6 +93,12 @@ inline constexpr int qMetaTypeId();
#else
# define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F)
#endif
+#ifndef QT_NO_VARIANT
+# define QT_FOR_EACH_STATIC_QVARIANT(F) \
+ F(QVariant, 41, QVariant)
+#else
+# define QT_FOR_EACH_STATIC_QVARIANT(F)
+#endif
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
F(QChar, 7, QChar) \
@@ -113,7 +120,7 @@ inline constexpr int qMetaTypeId();
F(QPointF, 26, QPointF) \
QT_FOR_EACH_STATIC_EASINGCURVE(F) \
F(QUuid, 30, QUuid) \
- F(QVariant, 41, QVariant) \
+ QT_FOR_EACH_STATIC_QVARIANT(F) \
QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \
F(QJsonValue, 45, QJsonValue) \
F(QJsonObject, 46, QJsonObject) \
@@ -128,13 +135,20 @@ inline constexpr int qMetaTypeId();
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
F(QObjectStar, 39, QObject*)
-#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
+#ifndef QT_NO_VARIANT
+# define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
F(QVariantMap, 8, QVariantMap) \
F(QVariantList, 9, QVariantList) \
F(QVariantHash, 28, QVariantHash) \
F(QVariantPair, 58, QVariantPair) \
F(QByteArrayList, 49, QByteArrayList) \
F(QStringList, 11, QStringList) \
+ /**/
+#else
+# define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
+ F(QByteArrayList, 49, QByteArrayList) \
+ F(QStringList, 11, QStringList)
+#endif
#if QT_CONFIG(shortcut)
#define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)\
@@ -188,12 +202,20 @@ inline constexpr int qMetaTypeId();
F(UInt, -1, uint, "quint32") \
F(LongLong, -1, qlonglong, "qint64") \
F(ULongLong, -1, qulonglong, "quint64") \
+ F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \
+ F(QStringList, -1, QStringList, "QList<QString>") \
+ QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F)
+
+#ifndef QT_NO_VARIANT
+#define QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F) \
F(QVariantList, -1, QVariantList, "QList<QVariant>") \
F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
F(QVariantPair, -1, QVariantPair, "QPair<QVariant,QVariant>") \
- F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \
- F(QStringList, -1, QStringList, "QList<QString>") \
+ /**/
+#else
+#define QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F)
+#endif
#define QT_FOR_EACH_STATIC_TYPE(F)\
QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
@@ -246,7 +268,14 @@ using NonConstMetaTypeInterface = const QMetaTypeInterface;
class QMetaTypeInterface
{
public:
- ushort revision; // 0 in Qt 6.0. Can increase if new field are added
+
+ /* Revision: Can increase if new field are added, or if semantics changes
+ 0: Initial Revision
+ 1: the meaning of the NeedsDestruction flag changed
+ */
+ static inline constexpr ushort CurrentRevision = 1;
+
+ ushort revision;
ushort alignment;
uint size;
uint flags;
@@ -485,23 +514,25 @@ public:
#endif
#endif
+ QMetaType underlyingType() const;
+
template<typename T>
constexpr static QMetaType fromType();
static QMetaType fromName(QByteArrayView name);
-
- friend bool operator==(QMetaType a, QMetaType b)
+private:
+ friend bool comparesEqual(const QMetaType &lhs,
+ const QMetaType &rhs) noexcept
{
- if (a.d_ptr == b.d_ptr)
+ if (lhs.d_ptr == rhs.d_ptr)
return true;
- if (!a.d_ptr || !b.d_ptr)
+ if (!lhs.d_ptr || !rhs.d_ptr)
return false; // one type is undefined, the other is defined
// avoid id call if we already have the id
- const int aId = a.id();
- const int bId = b.id();
+ const int aId = lhs.id();
+ const int bId = rhs.id();
return aId == bId;
}
- friend bool operator!=(QMetaType a, QMetaType b) { return !(a == b); }
-
+ Q_DECLARE_EQUALITY_COMPARABLE(QMetaType)
#ifndef QT_NO_DEBUG_STREAM
private:
friend Q_CORE_EXPORT QDebug operator<<(QDebug d, QMetaType m);
@@ -606,8 +637,7 @@ public:
const From *f = static_cast<const From *>(from);
To *t = static_cast<To *>(to);
auto &&r = function(*f);
- if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<decltype(r)>>,
- std::optional<To>>) {
+ if constexpr (std::is_same_v<q20::remove_cvref_t<decltype(r)>, std::optional<To>>) {
if (!r)
return false;
*t = *std::forward<decltype(r)>(r);
@@ -1721,11 +1751,19 @@ QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+// out-of-line helpers to reduce template code bloat ("SCARY") and improve compile times:
+Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m);
+Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m);
+}
+
template <typename T>
inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter()
{
- const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
- if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType::fromType<T>())) {
QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o);
}
@@ -1757,8 +1795,7 @@ struct SequentialValueTypeIsMetaType<T, true>
{
static bool registerConverter()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
- if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
QSequentialIterableConvertFunctor<T> o;
return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o);
}
@@ -1767,8 +1804,7 @@ struct SequentialValueTypeIsMetaType<T, true>
static bool registerMutableView()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
- if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
QSequentialIterableMutableViewFunctor<T> o;
return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o);
}
@@ -1801,8 +1837,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T
{
static bool registerConverter()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
- if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
QAssociativeIterableConvertFunctor<T> o;
return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o);
}
@@ -1811,8 +1846,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T
static bool registerMutableView()
{
- const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
- if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
+ if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
QAssociativeIterableMutableViewFunctor<T> o;
return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o);
}
@@ -2227,6 +2261,7 @@ struct is_std_pair<std::pair<T1_, T2_>> : std::true_type {
using T2 = T2_;
};
+namespace TypeNameHelper {
template<typename T>
constexpr auto typenameHelper()
{
@@ -2268,15 +2303,15 @@ constexpr auto typenameHelper()
QT_STRINGIFY(QT_NAMESPACE) "::"
#endif
#if defined(Q_CC_MSVC) && defined(Q_CC_CLANG)
- "auto __cdecl QtPrivate::typenameHelper(void) [T = "
+ "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper(void) [T = "
#elif defined(Q_CC_MSVC)
- "auto __cdecl QtPrivate::typenameHelper<"
+ "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper<"
#elif defined(Q_CC_CLANG)
- "auto QtPrivate::typenameHelper() [T = "
+ "auto QtPrivate::TypeNameHelper::typenameHelper() [T = "
#elif defined(Q_CC_GHS)
- "auto QtPrivate::typenameHelper<T>()[with T="
+ "auto QtPrivate::TypeNameHelper::typenameHelper<T>()[with T="
#else
- "constexpr auto QtPrivate::typenameHelper() [with T = "
+ "constexpr auto QtPrivate::TypeNameHelper::typenameHelper() [with T = "
#endif
) - 1;
#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
@@ -2302,6 +2337,8 @@ constexpr auto typenameHelper()
return result;
}
}
+} // namespace TypeNameHelper
+using TypeNameHelper::typenameHelper;
template<typename T, typename = void>
struct BuiltinMetaType : std::integral_constant<int, 0>
@@ -2358,18 +2395,20 @@ struct QDebugStreamOperatorForType <T, false>
template<typename T, bool = QTypeTraits::has_stream_operator_v<QDataStream, T>>
struct QDataStreamOperatorForType
{
- static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
- { ds << *reinterpret_cast<const T *>(a); }
- static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
- { ds >> *reinterpret_cast<T *>(a); }
+ static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr;
+ static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
};
+#ifndef QT_NO_DATASTREAM
template<typename T>
-struct QDataStreamOperatorForType <T, false>
+struct QDataStreamOperatorForType <T, true>
{
- static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr;
- static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
+ static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
+ { ds << *reinterpret_cast<const T *>(a); }
+ static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
+ { ds >> *reinterpret_cast<T *>(a); }
};
+#endif
// Performance optimization:
//
@@ -2462,7 +2501,7 @@ struct QMetaTypeInterfaceWrapper
using InterfaceType = std::conditional_t<IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface>;
static inline InterfaceType metaType = {
- /*.revision=*/ 0,
+ /*.revision=*/ QMetaTypeInterface::CurrentRevision,
/*.alignment=*/ alignof(T),
/*.size=*/ sizeof(T),
/*.flags=*/ QMetaTypeForType<T>::Flags,