summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qmetatype.cpp')
-rw-r--r--src/corelib/kernel/qmetatype.cpp300
1 files changed, 223 insertions, 77 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 81647eb5dc..1c2665e53c 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -5,7 +5,6 @@
#include "qmetatype.h"
#include "qmetatype_p.h"
-#include "qobject.h"
#include "qobjectdefs.h"
#include "qdatetime.h"
#include "qbytearray.h"
@@ -21,14 +20,14 @@
#include "qeasingcurve.h"
#endif
#include "quuid.h"
-#include "qvariant.h"
-#include "qdatastream.h"
#if QT_CONFIG(regularexpression)
# include "qregularexpression.h"
#endif
#ifndef QT_BOOTSTRAPPED
+# include "qdatastream.h"
+
# include "qbitarray.h"
# include "qurl.h"
# include "qvariant.h"
@@ -43,6 +42,7 @@
# include "qmetaobject.h"
# include "qsequentialiterable.h"
# include "qassociativeiterable.h"
+# include "qobject.h"
#endif
#if QT_CONFIG(itemmodel)
@@ -56,7 +56,6 @@
# include "qline.h"
#endif
-#include <bitset>
#include <new>
#include <cstring>
@@ -84,6 +83,20 @@ struct QMetaTypeDeleter
struct QMetaTypeCustomRegistry
{
+
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
+ QMetaTypeCustomRegistry()
+ {
+ /* qfloat16 was neither a builtin, nor unconditionally registered
+ in QtCore in Qt <= 6.2.
+ Inserting it as an alias ensures that a QMetaType::id call
+ will get the correct built-in type-id (the interface pointers
+ might still not match, but we already deal with that case.
+ */
+ aliases.insert("qfloat16", QtPrivate::qMetaTypeInterfaceForType<qfloat16>());
+ }
+#endif
+
QReadWriteLock lock;
QList<const QtPrivate::QMetaTypeInterface *> registry;
QHash<QByteArray, const QtPrivate::QMetaTypeInterface *> aliases;
@@ -137,13 +150,7 @@ struct QMetaTypeCustomRegistry
auto &ti = registry[idx];
// We must unregister all names.
- auto it = aliases.begin();
- while (it != aliases.end()) {
- if (it.value() == ti)
- it = aliases.erase(it);
- else
- ++it;
- }
+ aliases.removeIf([ti] (const auto &kv) { return kv.value() == ti; });
ti = nullptr;
@@ -255,7 +262,7 @@ const char *QtMetaTypePrivate::typedefNameForType(const QtPrivate::QMetaTypeInte
\li Pointers to classes derived from QObject
\li QList<T>, QQueue<T>, QStack<T> or QSet<T>
where T is a registered meta type
- \li QHash<T1, T2>, QMap<T1, T2> or QPair<T1, T2> where T1 and T2 are
+ \li QHash<T1, T2>, QMap<T1, T2> or std::pair<T1, T2> where T1 and T2 are
registered meta types
\li QPointer<T>, QSharedPointer<T>, QWeakPointer<T>, where T is a class that derives from QObject
\li Enumerations registered with Q_ENUM or Q_FLAG
@@ -433,23 +440,23 @@ const char *QtMetaTypePrivate::typedefNameForType(const QtPrivate::QMetaTypeInte
The enum describes attributes of a type supported by QMetaType.
- \value NeedsConstruction This type has a non-trivial default constructor. If the flag is not set, instances can be safely initialized with memset to 0.
- \value NeedsCopyConstruction (since 6.5) This type has a non-trivial copy construtcor. If the flag is not set, instances can be copied with memcpy.
+ \value NeedsConstruction This type has a default constructor. If the flag is not set, instances can be safely initialized with memset to 0.
+ \value NeedsCopyConstruction (since 6.5) This type has a non-trivial copy constructor. If the flag is not set, instances can be copied with memcpy.
\value NeedsMoveConstruction (since 6.5) This type has a non-trivial move constructor. If the flag is not set, instances can be moved with memcpy.
- \value NeedsDestruction This type has a non-trivial destructor. If the flag is not set calls to the destructor are not necessary before discarding objects.
+ \value NeedsDestruction This type has a non-trivial destructor. If the flag is not set, calls to the destructor are not necessary before discarding objects.
\value RelocatableType An instance of a type having this attribute can be safely moved to a different memory location using memcpy.
\omitvalue MovableType
\omitvalue SharedPointerToQObject
\value IsEnumeration This type is an enumeration.
\value IsUnsignedEnumeration If the type is an Enumeration, its underlying type is unsigned.
- \value PointerToQObject This type is a pointer to a derived of QObject.
+ \value PointerToQObject This type is a pointer to a class derived from QObject.
\value IsPointer This type is a pointer to another type.
\omitvalue WeakPointerToQObject
\omitvalue TrackingPointerToQObject
- \omitvalue IsGadget \omit This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. \endomit
+ \omitvalue IsGadget \omit (since Qt 5.5) This type is a Q_GADGET and its corresponding QMetaObject can be accessed with QMetaType::metaObject. \endomit
\omitvalue PointerToGadget
\omitvalue IsQmlList
- \value IsConst Indicates that values of this types are immutable; for instance because they are pointers to const objects.
+ \value IsConst Indicates that values of this type are immutable; for instance, because they are pointers to const objects.
\note Before Qt 6.5, both the NeedsConstruction and NeedsDestruction flags
were incorrectly set if the either copy construtor or destructor were
@@ -467,6 +474,7 @@ const char *QtMetaTypePrivate::typedefNameForType(const QtPrivate::QMetaTypeInte
\ingroup objectmodel
\threadsafe
+ \compares equality
The class is used as a helper to marshall types in QVariant and
in queued signals and slots connections. It associates a type
@@ -893,13 +901,22 @@ bool QMetaType::isOrdered() const
*/
void QMetaType::unregisterMetaType(QMetaType type)
{
- if (type.d_ptr && type.d_ptr->typeId.loadRelaxed() >= QMetaType::User) {
- // this is a custom meta type (not read-only)
- auto d = const_cast<QtPrivate::QMetaTypeInterface *>(type.d_ptr);
- if (auto reg = customTypeRegistry())
- reg->unregisterDynamicType(d->typeId.loadRelaxed());
- d->typeId.storeRelease(0);
+ const QtPrivate::QMetaTypeInterface *d_ptr = type.d_ptr;
+ if (!d_ptr)
+ return;
+
+ const int typeId = d_ptr->typeId.loadRelaxed();
+ if (typeId < QMetaType::User)
+ return;
+
+ // this is a custom meta type (not read-only)
+
+ if (auto reg = customTypeRegistry()) {
+ Q_ASSERT(reg->getCustomType(typeId) == d_ptr);
+ reg->unregisterDynamicType(typeId);
}
+
+ const_cast<QtPrivate::QMetaTypeInterface *>(d_ptr)->typeId.storeRelease(0);
}
/*!
@@ -909,22 +926,28 @@ void QMetaType::unregisterMetaType(QMetaType type)
Returns the QMetaType corresponding to the type in the template parameter.
*/
-/*! \fn bool QMetaType::operator==(QMetaType a, QMetaType b)
+/*! \fn bool QMetaType::operator==(const QMetaType &lhs, const QMetaType &rhs)
\since 5.15
\overload
- Returns \c true if the QMetaType \a a represents the same type
- as the QMetaType \a b, otherwise returns \c false.
+ Returns \c true if the QMetaType \a lhs represents the same type
+ as the QMetaType \a rhs, otherwise returns \c false.
*/
-/*! \fn bool QMetaType::operator!=(QMetaType a, QMetaType b)
+/*! \fn bool QMetaType::operator!=(const QMetaType &lhs, const QMetaType &rhs)
\since 5.15
\overload
- Returns \c true if the QMetaType \a a represents a different type
- than the QMetaType \a b, otherwise returns \c false.
+ Returns \c true if the QMetaType \a lhs represents a different type
+ than the QMetaType \a rhs, otherwise returns \c false.
*/
+/*! \internal */
+bool QMetaTypeModuleHelper::convert(const void *, int, void *, int) const
+{
+ return false;
+}
+
#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
{ #RealName, sizeof(#RealName) - 1, MetaTypeId },
@@ -940,7 +963,8 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ
{nullptr, 0, QMetaType::UnknownType}
};
-static const struct : QMetaTypeModuleHelper
+// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class
+static constexpr struct : QMetaTypeModuleHelper
{
template<typename T, typename LiteralWrapper =
std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView, const char *>>
@@ -987,6 +1011,8 @@ static const struct : QMetaTypeModuleHelper
using Double = double;
using Bool = bool;
using Nullptr = std::nullptr_t;
+ using Char16 = char16_t;
+ using Char32 = char32_t;
#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From) \
QMETATYPE_CONVERTER(To, From, result = double(source); return true;)
@@ -1141,6 +1167,9 @@ static const struct : QMetaTypeModuleHelper
QMETATYPE_CONVERTER_ASSIGN_QCHAR(ULong);
QMETATYPE_CONVERTER_ASSIGN_QCHAR(UInt);
QMETATYPE_CONVERTER_ASSIGN_QCHAR(ULongLong);
+ QMETATYPE_CONVERTER_ASSIGN_QCHAR(Char16);
+
+ QMETATYPE_CONVERTER(Char16, QChar, result = source.unicode(); return true;)
// conversions to QString
QMETATYPE_CONVERTER_ASSIGN(QString, QChar);
@@ -1178,6 +1207,14 @@ static const struct : QMetaTypeModuleHelper
result = QString::fromLatin1(&s, 1);
return true;
);
+ QMETATYPE_CONVERTER(QString, Char16,
+ result = QChar(source);
+ return true;
+ );
+ QMETATYPE_CONVERTER(QString, Char32,
+ result = QChar::fromUcs4(source).operator QStringView().toString();
+ return true;
+ );
#if QT_CONFIG(datestring)
QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate); return true;);
QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs); return true;);
@@ -1240,34 +1277,36 @@ static const struct : QMetaTypeModuleHelper
QMETATYPE_CONVERTER_ASSIGN(QRectF, QRect);
QMETATYPE_CONVERTER(QPoint, QPointF, result = source.toPoint(); return true;);
QMETATYPE_CONVERTER_ASSIGN(QPointF, QPoint);
- #endif
+#endif
+
+ QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source; return true;);
+#ifndef QT_NO_VARIANT
QMETATYPE_CONVERTER(QByteArrayList, QVariantList,
result.reserve(source.size());
- for (auto v: source)
+ for (const auto &v: source)
result.append(v.toByteArray());
return true;
);
QMETATYPE_CONVERTER(QVariantList, QByteArrayList,
result.reserve(source.size());
- for (auto v: source)
+ for (const auto &v: source)
result.append(QVariant(v));
return true;
);
QMETATYPE_CONVERTER(QStringList, QVariantList,
result.reserve(source.size());
- for (auto v: source)
+ for (const auto &v: source)
result.append(v.toString());
return true;
);
QMETATYPE_CONVERTER(QVariantList, QStringList,
result.reserve(source.size());
- for (auto v: source)
+ for (const auto &v: source)
result.append(QVariant(v));
return true;
);
- QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source; return true;);
QMETATYPE_CONVERTER(QVariantHash, QVariantMap,
for (auto it = source.begin(); it != source.end(); ++it)
@@ -1279,7 +1318,7 @@ static const struct : QMetaTypeModuleHelper
result.insert(it.key(), it.value());
return true;
);
-
+#endif // !QT_NO_VARIANT
#ifndef QT_BOOTSTRAPPED
QMETATYPE_CONVERTER_ASSIGN(QCborValue, QString);
QMETATYPE_CONVERTER(QString, QCborValue,
@@ -1679,17 +1718,17 @@ private:
QHash<Key, T> map;
};
-typedef QMetaTypeFunctionRegistry<QMetaType::ConverterFunction,QPair<int,int> >
-QMetaTypeConverterRegistry;
+using QMetaTypeConverterRegistry
+ = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<int,int>>;
Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
using QMetaTypeMutableViewRegistry
- = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, QPair<int,int>>;
+ = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<int,int>>;
Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
/*!
- \fn bool QMetaType::registerConverter()
+ \fn template<typename From, typename To> bool QMetaType::registerConverter()
\since 5.2
Registers the possibility of an implicit conversion from type From to type To in the meta
type system. Returns \c true if the registration succeeded, otherwise false.
@@ -1741,7 +1780,7 @@ Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
*/
bool QMetaType::registerConverterFunction(const ConverterFunction &f, QMetaType from, QMetaType to)
{
- if (!customTypesConversionRegistry()->insertIfNotContains(qMakePair(from.id(), to.id()), f)) {
+ if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
qWarning("Type conversion already registered from type %s to type %s",
from.name(), to.name());
return false;
@@ -1774,7 +1813,7 @@ bool QMetaType::registerConverterFunction(const ConverterFunction &f, QMetaType
*/
bool QMetaType::registerMutableViewFunction(const MutableViewFunction &f, QMetaType from, QMetaType to)
{
- if (!customTypesMutableViewRegistry()->insertIfNotContains(qMakePair(from.id(), to.id()), f)) {
+ if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
qWarning("Mutable view on type already registered from type %s to type %s",
from.name(), to.name());
return false;
@@ -1842,7 +1881,7 @@ bool QMetaType::debugStream(QDebug& dbg, const void *rhs)
*/
/*!
- \fn bool QMetaType::hasRegisteredDebugStreamOperator()
+ \fn template<typename T> bool QMetaType::hasRegisteredDebugStreamOperator()
\deprecated
\since 5.2
@@ -1947,18 +1986,17 @@ static bool convertFromEnum(QMetaType fromType, const void *from, QMetaType toTy
if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
}
- Q_ASSERT(toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray);
#ifndef QT_NO_QOBJECT
QMetaEnum en = metaEnumFromType(fromType);
if (en.isValid()) {
if (en.isFlag()) {
- const QByteArray keys = en.valueToKeys(ll);
+ const QByteArray keys = en.valueToKeys(static_cast<int>(ll));
if (toType.id() == QMetaType::QString)
*static_cast<QString *>(to) = QString::fromUtf8(keys);
else
*static_cast<QByteArray *>(to) = keys;
} else {
- const char *key = en.valueToKey(ll);
+ const char *key = en.valueToKey(static_cast<int>(ll));
if (toType.id() == QMetaType::QString)
*static_cast<QString *>(to) = QString::fromUtf8(key);
else
@@ -1967,6 +2005,8 @@ static bool convertFromEnum(QMetaType fromType, const void *from, QMetaType toTy
return true;
}
#endif
+ if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
+ return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
return false;
}
@@ -1978,12 +2018,12 @@ static bool convertToEnum(QMetaType fromType, const void *from, QMetaType toType
#ifndef QT_NO_QOBJECT
if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
QMetaEnum en = metaEnumFromType(toType);
- if (!en.isValid())
- return false;
- QByteArray keys = (fromTypeId == QMetaType::QString)
- ? static_cast<const QString *>(from)->toUtf8()
- : *static_cast<const QByteArray *>(from);
- value = en.keysToValue(keys.constData(), &ok);
+ if (en.isValid()) {
+ QByteArray keys = (fromTypeId == QMetaType::QString)
+ ? static_cast<const QString *>(from)->toUtf8()
+ : *static_cast<const QByteArray *>(from);
+ value = en.keysToValue(keys.constData(), &ok);
+ }
}
#endif
if (!ok) {
@@ -2060,13 +2100,12 @@ static bool convertIterableToVariantHash(QMetaType fromType, const void *from, v
h.insert(it.key().toString(), it.value());
return true;
}
-#endif
static bool convertIterableToVariantPair(QMetaType fromType, const void *from, void *to)
{
- const QMetaType::ConverterFunction * const f =
- customTypesConversionRegistry()->function(qMakePair(fromType.id(),
- qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>()));
+ const int targetId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+ const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
+
if (!f)
return false;
@@ -2092,7 +2131,6 @@ static bool convertIterableToVariantPair(QMetaType fromType, const void *from, v
return true;
}
-#ifndef QT_BOOTSTRAPPED
static bool convertToSequentialIterable(QMetaType fromType, const void *from, void *to)
{
using namespace QtMetaTypePrivate;
@@ -2218,6 +2256,9 @@ static bool convertToAssociativeIterable(QMetaType fromType, const void *from, v
static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
{
+ if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
+ return false; // Can not convert between pointer and value
+
const QMetaObject *f = fromType.metaObject();
const QMetaObject *t = toType.metaObject();
if (f && t) {
@@ -2288,7 +2329,8 @@ static bool convertMetaObject(QMetaType fromType, const void *from, QMetaType to
*static_cast<void **>(to) = nullptr;
return fromType.metaObject()->inherits(toType.metaObject());
}
- } else {
+ } else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
+ // fromType and toType are of same 'pointedness'
const QMetaObject *f = fromType.metaObject();
const QMetaObject *t = toType.metaObject();
if (f && t && f->inherits(t)) {
@@ -2299,7 +2341,7 @@ static bool convertMetaObject(QMetaType fromType, const void *from, QMetaType to
}
return false;
}
-#endif
+#endif // !QT_BOOTSTRAPPED
/*!
\fn bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId)
@@ -2340,8 +2382,7 @@ bool QMetaType::convert(QMetaType fromType, const void *from, QMetaType toType,
if (moduleHelper->convert(from, fromTypeId, to, toTypeId))
return true;
}
- const QMetaType::ConverterFunction * const f =
- customTypesConversionRegistry()->function(qMakePair(fromTypeId, toTypeId));
+ const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
if (f)
return (*f)(from, to);
@@ -2357,10 +2398,11 @@ bool QMetaType::convert(QMetaType fromType, const void *from, QMetaType toType,
}
}
+#ifndef QT_BOOTSTRAPPED
+# ifndef QT_NO_VARIANT
if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
return true;
-#ifndef QT_BOOTSTRAPPED
// handle iterables
if (toTypeId == QVariantList && convertIterableToVariantList(fromType, from, to))
return true;
@@ -2370,6 +2412,7 @@ bool QMetaType::convert(QMetaType fromType, const void *from, QMetaType toType,
if (toTypeId == QVariantHash && convertIterableToVariantHash(fromType, from, to))
return true;
+# endif
if (toTypeId == qMetaTypeId<QSequentialIterable>())
return convertToSequentialIterable(fromType, from, to);
@@ -2396,8 +2439,7 @@ bool QMetaType::view(QMetaType fromType, void *from, QMetaType toType, void *to)
int fromTypeId = fromType.id();
int toTypeId = toType.id();
- const QMetaType::MutableViewFunction * const f =
- customTypesMutableViewRegistry()->function(qMakePair(fromTypeId, toTypeId));
+ const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
if (f)
return (*f)(from, to);
@@ -2439,8 +2481,7 @@ bool QMetaType::canView(QMetaType fromType, QMetaType toType)
if (fromTypeId == UnknownType || toTypeId == UnknownType)
return false;
- const MutableViewFunction * const f =
- customTypesMutableViewRegistry()->function(qMakePair(fromTypeId, toTypeId));
+ const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
if (f)
return true;
@@ -2555,7 +2596,8 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
if (toTypeId == qMetaTypeId<QAssociativeIterable>())
return canConvertToAssociativeIterable(fromType);
-
+#endif
+#ifndef QT_NO_VARIANT
if (toTypeId == QVariantList
&& canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
return true;
@@ -2565,11 +2607,11 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
&& canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
return true;
}
-#endif
if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
return true;
+#endif
if (fromType.flags() & IsEnumeration) {
if (toTypeId == QString || toTypeId == QByteArray)
@@ -2601,7 +2643,7 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
*/
/*!
- \fn bool QMetaType::hasRegisteredConverterFunction()
+ \fn template<typename From, typename To> bool QMetaType::hasRegisteredConverterFunction()
Returns \c true, if the meta type system has a registered conversion from type From to type To.
\since 5.2
\overload
@@ -2614,11 +2656,41 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
*/
bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType)
{
- return customTypesConversionRegistry()->contains(qMakePair(fromType.id(), toType.id()));
+ return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for IsMetaTypePair::registerConverter().
+*/
+bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+ return QMetaType::hasRegisteredConverterFunction(m, to);
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerConverter().
+*/
+bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
+ return QMetaType::hasRegisteredConverterFunction(m, to);
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerConverter().
+*/
+bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
+ return QMetaType::hasRegisteredConverterFunction(m, to);
}
/*!
- \fn bool QMetaType::hasRegisteredMutableViewFunction()
+ \fn template<typename From, typename To> bool QMetaType::hasRegisteredMutableViewFunction()
Returns \c true, if the meta type system has a registered mutable view on type From of type To.
\since 6.0
\overload
@@ -2631,7 +2703,27 @@ bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toT
*/
bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType)
{
- return customTypesMutableViewRegistry()->contains(qMakePair(fromType.id(), toType.id()));
+ return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerMutableView().
+*/
+bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
+ return QMetaType::hasRegisteredMutableViewFunction(m, to);
+}
+
+/*!
+ \internal
+ Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerMutableView().
+*/
+bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
+{
+ const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
+ return QMetaType::hasRegisteredMutableViewFunction(m, to);
}
/*!
@@ -2882,6 +2974,59 @@ bool QMetaType::hasRegisteredDataStreamOperators() const
}
/*!
+ \since 6.6
+
+ If this metatype represents an enumeration, this method returns a
+ metatype of a numeric class of the same signedness and size as the
+ enums underlying type.
+ If it represents a QFlags type, it returns QMetaType::Int.
+ In all other cases an invalid QMetaType is returned.
+ */
+QMetaType QMetaType::underlyingType() const
+{
+ if (!d_ptr || !(flags() & IsEnumeration))
+ return {};
+ /* QFlags has enumeration set so that's handled here (qint32
+ case), as QFlags uses int as the underlying type
+ Note that we do some approximation here, as we cannot
+ differentiate between different underlying types of the
+ same size and signedness (consider char <-> (un)signed char,
+ int <-> long <-> long long).
+
+ ### TODO PENDING: QTBUG-111926 - QFlags supporting >32 bit int
+ */
+ if (flags() & IsUnsignedEnumeration) {
+ switch (sizeOf()) {
+ case 1:
+ return QMetaType::fromType<quint8>();
+ case 2:
+ return QMetaType::fromType<quint16>();
+ case 4:
+ return QMetaType::fromType<quint32>();
+ case 8:
+ return QMetaType::fromType<quint64>();
+ default:
+ break;
+ }
+ } else {
+ switch (sizeOf()) {
+ case 1:
+ return QMetaType::fromType<qint8>();
+ case 2:
+ return QMetaType::fromType<qint16>();
+ case 4:
+ return QMetaType::fromType<qint32>();
+ case 8:
+ return QMetaType::fromType<qint64>();
+ default:
+ break;
+ }
+ }
+ // int128 can be handled above once we have qint128
+ return QMetaType();
+}
+
+/*!
\fn bool QMetaType::load(QDataStream &stream, int type, void *data)
\overload
\deprecated
@@ -2993,7 +3138,7 @@ QMetaType QMetaType::fromName(QByteArrayView typeName)
*/
/*!
- \fn int qRegisterMetaType(const char *typeName)
+ \fn template <typename T> int qRegisterMetaType(const char *typeName)
\relates QMetaType
\obsolete
\threadsafe
@@ -3027,7 +3172,7 @@ QMetaType QMetaType::fromName(QByteArrayView typeName)
*/
/*!
- \fn int qRegisterMetaType()
+ \fn template <typename T> int qRegisterMetaType()
\relates QMetaType
\threadsafe
\since 4.2
@@ -3083,7 +3228,7 @@ QMetaType QMetaType::fromName(QByteArrayView typeName)
*/
/*!
- \fn int qMetaTypeId()
+ \fn template <typename T> int qMetaTypeId()
\relates QMetaType
\threadsafe
\since 4.1
@@ -3148,6 +3293,7 @@ QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_METATYPE_DECLARE_TEMPLATE_ITER)
QT_FOR_EACH_STATIC_CORE_CLASS(QT_METATYPE_DECLARE_TEMPLATE_ITER)
QT_FOR_EACH_STATIC_CORE_POINTER(QT_METATYPE_DECLARE_TEMPLATE_ITER)
QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_METATYPE_DECLARE_TEMPLATE_ITER)
+
#undef QT_METATYPE_DECLARE_TEMPLATE_ITER
#endif
}