summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp5
-rw-r--r--src/corelib/io/qsettings.cpp5
-rw-r--r--src/corelib/kernel/qmetatype.cpp371
-rw-r--r--src/corelib/kernel/qmetatype.h155
-rw-r--r--src/corelib/kernel/qmimedata.cpp6
-rw-r--r--src/corelib/kernel/qvariant.cpp7
-rw-r--r--src/corelib/serialization/qcborcommon.h2
-rw-r--r--src/corelib/tools/qbitarray.h2
8 files changed, 176 insertions, 377 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp
index d28a0ac956..a91458cc95 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetatype.cpp
@@ -97,11 +97,6 @@ qRegisterMetaType<MyClass>("MyClass");
//! [4]
-//! [5]
-qRegisterMetaTypeStreamOperators<MyClass>("MyClass");
-//! [5]
-
-
//! [6]
QDataStream &operator<<(QDataStream &out, const MyClass &myObj);
QDataStream &operator>>(QDataStream &in, MyClass &myObj);
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 6165cd2af2..0a62ffb2be 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1979,8 +1979,9 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet code/src_corelib_io_qsettings.cpp 1
- Custom types registered using qRegisterMetaType() and
- qRegisterMetaTypeStreamOperators() can be stored using QSettings.
+ Custom types registered using qRegisterMetaType() that have
+ operators for streaming to and from a QDataStream can be stored
+ using QSettings.
\section1 Section and Key Syntax
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 1422e60a1c..7440f58a1c 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -105,14 +105,6 @@ struct QMetaTypeCustomRegistry
QReadWriteLock lock;
QList<QtPrivate::QMetaTypeInterface *> registry;
QHash<QByteArray, QtPrivate::QMetaTypeInterface *> aliases;
-#ifndef QT_NO_DATASTREAM
- struct DataStreamOps
- {
- QMetaType::SaveOperator saveOp;
- QMetaType::LoadOperator loadOp;
- };
- QHash<int, DataStreamOps> dataStreamOp;
-#endif
// index of first empty (unregistered) type in registry, if any.
int firstEmpty = 0;
@@ -246,6 +238,15 @@ Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)
\li Classes that have a Q_GADGET macro
\endlist
+ \note This method also registers the stream and debug operators for the type if they
+ are visible at registration time. As this is done automatically in some places,
+ it is strongly recommended to declare the stream operators for a type directly
+ after the type itself.
+
+ The stream operators should have the following signatures:
+
+ \snippet code/src_corelib_kernel_qmetatype.cpp 6
+
\sa qRegisterMetaType()
*/
@@ -902,11 +903,8 @@ private:
typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractConverterFunction,QPair<int,int> >
QMetaTypeConverterRegistry;
-typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
-QMetaTypeDebugStreamRegistry;
Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
-Q_GLOBAL_STATIC(QMetaTypeDebugStreamRegistry, customTypesDebugStreamRegistry)
/*!
\fn bool QMetaType::registerConverter()
@@ -939,15 +937,6 @@ Q_GLOBAL_STATIC(QMetaTypeDebugStreamRegistry, customTypesDebugStreamRegistry)
to type To in the meta type system. Returns \c true if the registration succeeded, otherwise false.
*/
-#ifndef QT_NO_DEBUG_STREAM
-/*!
- \fn bool QMetaType::registerDebugStreamOperator()
- Registers the debug stream operator for the user-registered type T. This requires T to have
- an operator<<(QDebug dbg, T).
- Returns \c true if the registration succeeded, otherwise false.
-*/
-#endif
-
/*!
Registers function \a f as converter function from type id \a from to \a to.
If there's already a conversion registered, this does nothing but deleting \a f.
@@ -978,30 +967,54 @@ void QMetaType::unregisterConverterFunction(int from, int to)
}
#ifndef QT_NO_DEBUG_STREAM
-bool QMetaType::registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f,
- int type)
+
+/*!
+ Streams the object at \a rhs of type \a typeId to the debug stream \a dbg. Returns \c true
+ on success, otherwise false.
+ \since 5.2
+*/
+bool QMetaType::debugStream(QDebug& dbg, const void *rhs)
{
- if (!customTypesDebugStreamRegistry()->insertIfNotContains(type, f)) {
- qWarning("Debug stream operator already registered for type %s", QMetaType::typeName(type));
+ if (!isValid() || !d_ptr->debugStream)
return false;
- }
+ d_ptr->debugStream(d_ptr, dbg, rhs);
return true;
}
/*!
+ \fn bool QMetaType::debugStream(QDebug& dbg, const void *rhs, int typeId)
+ \overload
+ \obsolete
+*/
+
+/*!
\fn bool QMetaType::hasRegisteredDebugStreamOperator()
- Returns \c true, if the meta type system has a registered debug stream operator for type T.
+ \obsolete
\since 5.2
+
+ Returns \c true, if the meta type system has a registered debug stream operator for type T.
*/
/*!
+ \fn bool QMetaType::hasRegisteredDebugStreamOperator(int typeId)
+ \obsolete
+
Returns \c true, if the meta type system has a registered debug stream operator for type
id \a typeId.
\since 5.2
*/
-bool QMetaType::hasRegisteredDebugStreamOperator(int typeId)
+
+/*!
+ \fn bool QMetaType::hasRegisteredDebugStreamOperator(int typeId)
+ \since 6.0
+
+ Returns \c true, if the meta type system has a registered debug stream operator for this
+ meta type.
+*/
+bool QMetaType::hasRegisteredDebugStreamOperator() const
+
{
- return customTypesDebugStreamRegistry()->contains(typeId);
+ return d_ptr && d_ptr->debugStream != nullptr;
}
#endif
@@ -1018,20 +1031,6 @@ bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId
}
/*!
- Streams the object at \a rhs of type \a typeId to the debug stream \a dbg. Returns \c true
- on success, otherwise false.
- \since 5.2
-*/
-bool QMetaType::debugStream(QDebug& dbg, const void *rhs, int typeId)
-{
- const QtPrivate::AbstractDebugStreamFunction * const f = customTypesDebugStreamRegistry()->function(typeId);
- if (!f)
- return false;
- f->stream(f, dbg, rhs);
- return true;
-}
-
-/*!
\fn bool QMetaType::hasRegisteredConverterFunction()
Returns \c true, if the meta type system has a registered conversion from type From to type To.
\since 5.2
@@ -1048,32 +1047,6 @@ bool QMetaType::hasRegisteredConverterFunction(int fromTypeId, int toTypeId)
return customTypesConversionRegistry()->contains(qMakePair(fromTypeId, toTypeId));
}
-#ifndef QT_NO_DATASTREAM
-/*!
- \internal
-*/
-void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
- LoadOperator loadOp)
-{
- registerStreamOperators(type(typeName), saveOp, loadOp);
-}
-
-/*!
- \internal
-*/
-void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
- LoadOperator loadOp)
-{
- if (idx < User)
- return; //builtin types should not be registered;
-
- if (auto reg = customTypeRegistry()) {
- QWriteLocker locker(&reg->lock);
- reg->dataStreamOp[idx] = { saveOp, loadOp };
- }
-}
-#endif // QT_NO_DATASTREAM
-
// We don't officially support constexpr in MSVC 2015, but the limited support it
// has is enough for the code below.
@@ -1315,218 +1288,90 @@ int QMetaType::type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
}
#ifndef QT_NO_DATASTREAM
-namespace
-{
-
-template<typename T>
-class HasStreamOperator
-{
- struct Yes { char unused[1]; };
- struct No { char unused[2]; };
- static_assert(sizeof(Yes) != sizeof(No));
-
- template<class C> static decltype(std::declval<QDataStream&>().operator>>(std::declval<C&>()), Yes()) load(int);
- template<class C> static decltype(operator>>(std::declval<QDataStream&>(), std::declval<C&>()), Yes()) load(int);
- template<class C> static No load(...);
- template<class C> static decltype(operator<<(std::declval<QDataStream&>(), std::declval<const C&>()), Yes()) saveFunction(int);
- template<class C> static decltype(std::declval<QDataStream&>().operator<<(std::declval<const C&>()), Yes()) saveMethod(int);
- template<class C> static No saveMethod(...);
- template<class C> static No saveFunction(...);
- static constexpr bool LoadValue = QtMetaTypePrivate::TypeDefinition<T>::IsAvailable && (sizeof(load<T>(0)) == sizeof(Yes));
- static constexpr bool SaveValue = QtMetaTypePrivate::TypeDefinition<T>::IsAvailable &&
- ((sizeof(saveMethod<T>(0)) == sizeof(Yes)) || (sizeof(saveFunction<T>(0)) == sizeof(Yes)));
-public:
- static constexpr bool Value = LoadValue && SaveValue;
-};
-
-// Quick sanity checks
-static_assert(HasStreamOperator<NS(QJsonDocument)>::Value);
-static_assert(!HasStreamOperator<void*>::Value);
-static_assert(HasStreamOperator<qint8>::Value);
-
-template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted && HasStreamOperator<T>::Value>
-struct FilteredOperatorSwitch
-{
- static bool load(QDataStream &stream, T *data, int)
- {
- stream >> *data;
- return true;
- }
- static bool save(QDataStream &stream, const T *data, int)
- {
- stream << *data;
- return true;
- }
-};
-
-template<typename T>
-struct FilteredOperatorSwitch<T, /* IsAcceptedType = */ false>
-{
- static const QMetaTypeModuleHelper *getMetaTypeInterface()
- {
- if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
- return qMetaTypeGuiHelper;
- else if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
- return qMetaTypeWidgetsHelper;
- return nullptr;
- }
- static bool save(QDataStream &stream, const T *data, int type)
- {
- if (auto interface = getMetaTypeInterface()) {
- return interface->save(stream, type, data);
- }
- return false;
- }
- static bool load(QDataStream &stream, T *data, int type)
- {
- if (auto interface = getMetaTypeInterface()) {
- return interface->load(stream, type, data);
- }
- return false;
- }
-};
-
-class SaveOperatorSwitch
-{
-public:
- QDataStream &stream;
- int m_type;
-
- template<typename T>
- bool delegate(const T *data)
- {
- return FilteredOperatorSwitch<T>::save(stream, data, m_type);
- }
- bool delegate(const char *data)
- {
- // force a char to be signed
- stream << qint8(*data);
- return true;
- }
- bool delegate(const long *data)
- {
- stream << qlonglong(*data);
- return true;
- }
- bool delegate(const unsigned long *data)
- {
- stream << qulonglong(*data);
- return true;
- }
- bool delegate(const QMetaTypeSwitcher::NotBuiltinType *data)
- {
- auto ct = customTypeRegistry();
- if (!ct)
- return false;
- QMetaType::SaveOperator op = nullptr;
- {
- QReadLocker lock(&ct->lock);
- op = ct->dataStreamOp.value(m_type).saveOp;
- }
- if (!op)
- return false;
- op(stream, data);
- return true;
- }
- bool delegate(const void*) { return false; }
- bool delegate(const QMetaTypeSwitcher::UnknownType*) { return false; }
-};
-class LoadOperatorSwitch
-{
-public:
- QDataStream &stream;
- int m_type;
-
- template<typename T>
- bool delegate(const T *data)
- {
- return FilteredOperatorSwitch<T>::load(stream, const_cast<T*>(data), m_type);
- }
- bool delegate(const char *data)
- {
- // force a char to be signed
- qint8 c;
- stream >> c;
- *const_cast<char*>(data) = c;
- return true;
- }
- bool delegate(const long *data)
- {
- qlonglong l;
- stream >> l;
- *const_cast<long*>(data) = l;
- return true;
- }
- bool delegate(const unsigned long *data)
- {
- qlonglong l;
- stream >> l;
- *const_cast<unsigned long*>(data) = l;
- return true;
- }
- bool delegate(const QMetaTypeSwitcher::NotBuiltinType *data)
- {
- auto ct = customTypeRegistry();
- if (!ct)
- return false;
- QMetaType::LoadOperator op = nullptr;
- {
- QReadLocker lock(&ct->lock);
- op = ct->dataStreamOp.value(m_type).loadOp;
- }
- if (!op)
- return false;
- op(stream, const_cast<QMetaTypeSwitcher::NotBuiltinType *>(data));
- return true;
- }
- bool delegate(const void*) { return false; }
- bool delegate(const QMetaTypeSwitcher::UnknownType*) { return false; }
-};
-} // namespace
-
/*!
Writes the object pointed to by \a data with the ID \a type to
the given \a stream. Returns \c true if the object is saved
successfully; otherwise returns \c false.
- The type must have been registered with qRegisterMetaType() and
- qRegisterMetaTypeStreamOperators() beforehand.
+ The type must have been registered with Q_DECLARE_METATYPE()
+ beforehand.
Normally, you should not need to call this function directly.
Instead, use QVariant's \c operator<<(), which relies on save()
to stream custom types.
- \sa load(), qRegisterMetaTypeStreamOperators()
+ \sa load()
*/
-bool QMetaType::save(QDataStream &stream, int type, const void *data)
+bool QMetaType::save(QDataStream &stream, const void *data) const
{
- if (!data)
+ if (!data || !isValid())
+ return false;
+
+ // keep compatibility for long/ulong
+ if (id() == QMetaType::Long) {
+ stream << qlonglong(*(long *)data);
+ return true;
+ } else if (id() == QMetaType::ULong) {
+ stream << qlonglong(*(unsigned long *)data);
+ return true;
+ }
+
+ if (!d_ptr->dataStreamOut)
return false;
- SaveOperatorSwitch saveOp{stream, type};
- return QMetaTypeSwitcher::switcher<bool>(saveOp, type, data);
+
+ d_ptr->dataStreamOut(d_ptr, stream, data);
+ return true;
}
/*!
+ \fn bool QMetaType::save(QDataStream &stream, int type, const void *data)
+ \overload
+ \obsolete
+*/
+
+/*!
Reads the object of the specified \a type from the given \a
stream into \a data. Returns \c true if the object is loaded
successfully; otherwise returns \c false.
- The type must have been registered with qRegisterMetaType() and
- qRegisterMetaTypeStreamOperators() beforehand.
+ The type must have been registered with Q_DECLARE_METATYPE()
+ beforehand.
Normally, you should not need to call this function directly.
Instead, use QVariant's \c operator>>(), which relies on load()
to stream custom types.
- \sa save(), qRegisterMetaTypeStreamOperators()
+ \sa save()
*/
-bool QMetaType::load(QDataStream &stream, int type, void *data)
+bool QMetaType::load(QDataStream &stream, void *data) const
{
- if (!data)
+ if (!data || !isValid())
return false;
- LoadOperatorSwitch loadOp{stream, type};
- return QMetaTypeSwitcher::switcher<bool>(loadOp, type, data);
+
+ // keep compatibility for long/ulong
+ if (id() == QMetaType::Long) {
+ qlonglong ll;
+ stream >> ll;
+ *(long *)data = long(ll);
+ return true;
+ } else if (id() == QMetaType::ULong) {
+ qulonglong ull;
+ stream >> ull;
+ *(unsigned long *)data = (unsigned long)(ull);
+ return true;
+ }
+ if (!d_ptr->dataStreamIn)
+ return false;
+
+ d_ptr->dataStreamIn(d_ptr, stream, data);
+ return true;
}
+
+/*!
+ \fn bool QMetaType::load(QDataStream &stream, int type, void *data)
+ \overload
+ \obsolete
+*/
#endif // QT_NO_DATASTREAM
/*!
@@ -1668,29 +1513,7 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
\warning This function is useful only for registering an alias (typedef)
for every other use case Q_DECLARE_METATYPE and qMetaTypeId() should be used instead.
- \sa {QMetaType::}{qRegisterMetaTypeStreamOperators()}, {QMetaType::}{isRegistered()},
- Q_DECLARE_METATYPE()
-*/
-
-/*!
- \fn void qRegisterMetaTypeStreamOperators(const char *typeName)
- \relates QMetaType
- \threadsafe
-
- Registers the stream operators for the type \c{T} called \a
- typeName.
-
- Afterward, the type can be streamed using QMetaType::load() and
- QMetaType::save(). These functions are used when streaming a
- QVariant.
-
- \snippet code/src_corelib_kernel_qmetatype.cpp 5
-
- The stream operators should have the following signatures:
-
- \snippet code/src_corelib_kernel_qmetatype.cpp 6
-
- \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
+ \sa {QMetaType::}{isRegistered()}, Q_DECLARE_METATYPE()
*/
/*!
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index ced3444020..8e8ecac0a0 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -249,7 +249,6 @@ inline constexpr int qMetaTypeId();
F(QPointer)
class QDataStream;
-class QMetaTypeInterface;
struct QMetaObject;
namespace QtPrivate
@@ -267,36 +266,6 @@ To convertImplicit(const From& from)
return from;
}
-#ifndef QT_NO_DEBUG_STREAM
-struct AbstractDebugStreamFunction
-{
- typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *);
- typedef void (*Destroy)(AbstractDebugStreamFunction *);
- explicit AbstractDebugStreamFunction(Stream s = nullptr, Destroy d = nullptr)
- : stream(s), destroy(d) {}
- Q_DISABLE_COPY(AbstractDebugStreamFunction)
- Stream stream;
- Destroy destroy;
-};
-
-template<typename T>
-struct BuiltInDebugStreamFunction : public AbstractDebugStreamFunction
-{
- BuiltInDebugStreamFunction()
- : AbstractDebugStreamFunction(stream, destroy) {}
- static void stream(const AbstractDebugStreamFunction *, QDebug& dbg, const void *r)
- {
- const T *rhs = static_cast<const T *>(r);
- operator<<(dbg, *rhs);
- }
-
- static void destroy(AbstractDebugStreamFunction *_this)
- {
- delete static_cast<BuiltInDebugStreamFunction *>(_this);
- }
-};
-#endif
-
struct AbstractConverterFunction
{
typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);
@@ -461,14 +430,6 @@ public:
};
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
- typedef void (*SaveOperator)(QDataStream &, const void *);
- typedef void (*LoadOperator)(QDataStream &, void *);
-#ifndef QT_NO_DATASTREAM
- static void registerStreamOperators(const char *typeName, SaveOperator saveOp,
- LoadOperator loadOp);
- static void registerStreamOperators(int type, SaveOperator saveOp,
- LoadOperator loadOp);
-#endif
static void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type);
static int type(const char *typeName);
@@ -484,11 +445,6 @@ public:
static void *construct(int type, void *where, const void *copy);
static void destruct(int type, void *where);
-#ifndef QT_NO_DATASTREAM
- static bool save(QDataStream &stream, int type, const void *data);
- static bool load(QDataStream &stream, int type, void *data);
-#endif
-
explicit QMetaType(int type);
explicit QMetaType(QtPrivate::QMetaTypeInterface *d);
constexpr QMetaType() : d_ptr(nullptr) {}
@@ -521,6 +477,20 @@ public:
bool isEqualityComparable() const;
bool isOrdered() const;
+#ifndef QT_NO_DATASTREAM
+ bool save(QDataStream &stream, const void *data) const;
+ bool load(QDataStream &stream, void *data) const;
+
+#if QT_DEPRECATED_SINCE(6, 0)
+ QT_DEPRECATED_VERSION_6_0
+ static bool save(QDataStream &stream, int type, const void *data)
+ { return QMetaType(type).save(stream, data); }
+ QT_DEPRECATED_VERSION_6_0
+ static bool load(QDataStream &stream, int type, void *data)
+ { return QMetaType(type).load(stream, data); }
+#endif
+#endif
+
template<typename T>
static QMetaType fromType();
@@ -530,22 +500,21 @@ public:
public:
#ifndef QT_NO_DEBUG_STREAM
- template<typename T>
- static bool registerDebugStreamOperator()
- {
- static_assert((!QMetaTypeId2<T>::IsBuiltIn),
- "QMetaType::registerDebugStreamOperator: The type must be a custom type.");
+ bool debugStream(QDebug& dbg, const void *rhs);
+ bool hasRegisteredDebugStreamOperator() const;
- const int typeId = qMetaTypeId<T>();
- static const QtPrivate::BuiltInDebugStreamFunction<T> f;
- return registerDebugStreamOperatorFunction(&f, typeId);
- }
+#if QT_DEPRECATED_SINCE(6, 0)
+ QT_DEPRECATED_VERSION_6_0
+ static bool debugStream(QDebug& dbg, const void *rhs, int typeId)
+ { return QMetaType(typeId).debugStream(dbg, rhs); }
template<typename T>
+ QT_DEPRECATED_VERSION_6_0
static bool hasRegisteredDebugStreamOperator()
- {
- return hasRegisteredDebugStreamOperator(qMetaTypeId<T>());
- }
- static bool hasRegisteredDebugStreamOperator(int typeId);
+ { return QMetaType::fromType<T>().hasRegisteredDebugStreamOperator(); }
+ QT_DEPRECATED_VERSION_6_0
+ static bool hasRegisteredDebugStreamOperator(int typeId)
+ { return QMetaType(typeId).hasRegisteredDebugStreamOperator(); }
+#endif
#endif
// implicit conversion supported like double -> float
@@ -628,8 +597,6 @@ public:
}
#endif
- static bool debugStream(QDebug& dbg, const void *rhs, int typeId);
-
template<typename From, typename To>
static bool hasRegisteredConverterFunction()
{
@@ -638,10 +605,6 @@ public:
static bool hasRegisteredConverterFunction(int fromTypeId, int toTypeId);
-#ifndef QT_NO_DEBUG_STREAM
- static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type);
-#endif
-
#ifndef Q_CLANG_QDOC
template<typename, bool> friend struct QtPrivate::ValueTypeIsMetaType;
template<typename, typename> friend struct QtPrivate::ConverterMemberFunction;
@@ -1751,20 +1714,6 @@ int qRegisterMetaType(const char *typeName
return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy, defined);
}
-#ifndef QT_NO_DATASTREAM
-template <typename T>
-void qRegisterMetaTypeStreamOperators(const char *typeName
-#ifndef Q_CLANG_QDOC
- , T * /* dummy */ = nullptr
-#endif
-)
-{
- qRegisterMetaType<T>(typeName);
- QMetaType::registerStreamOperators(typeName, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
-}
-#endif // QT_NO_DATASTREAM
-
template <typename T>
inline constexpr int qMetaTypeId()
{
@@ -1889,17 +1838,6 @@ struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
};
#endif
-#ifndef QT_NO_DATASTREAM
-template <typename T>
-inline int qRegisterMetaTypeStreamOperators()
-{
- int id = qMetaTypeId<T>();
- QMetaType::registerStreamOperators(id, QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Save,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Load);
- return id;
-}
-#endif
-
#define Q_DECLARE_OPAQUE_POINTER(POINTER) \
QT_BEGIN_NAMESPACE namespace QtPrivate { \
template <> \
@@ -2245,6 +2183,12 @@ public:
EqualsFn equals;
using LessThanFn = bool (*)(const QMetaTypeInterface *, const void *, const void *);
LessThanFn lessThan;
+ using DebugStreamFn = void (*)(const QMetaTypeInterface *, QDebug &, const void *);
+ DebugStreamFn debugStream;
+ using DataStreamOutFn = void (*)(const QMetaTypeInterface *, QDataStream &, const void *);
+ DataStreamOutFn dataStreamOut;
+ using DataStreamInFn = void (*)(const QMetaTypeInterface *, QDataStream &, void *);
+ DataStreamInFn dataStreamIn;
using LegacyRegisterOp = void (*)();
LegacyRegisterOp legacyRegisterOp;
@@ -2692,6 +2636,35 @@ struct QLessThanOperatorForType <T, false>
static constexpr QMetaTypeInterface::LessThanFn lessThan = nullptr;
};
+template<typename T, bool = QTypeTraits::has_ostream_operator_v<QDebug, T>>
+struct QDebugStreamOperatorForType
+{
+ static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
+ { dbg << *reinterpret_cast<const T *>(a); }
+};
+
+template<typename T>
+struct QDebugStreamOperatorForType <T, false>
+{
+ static constexpr QMetaTypeInterface::DebugStreamFn debugStream = nullptr;
+};
+
+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); }
+};
+
+template<typename T>
+struct QDataStreamOperatorForType <T, false>
+{
+ static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr;
+ static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
+};
+
template<typename S>
class QMetaTypeForType
{
@@ -2780,6 +2753,9 @@ QMetaTypeInterface QMetaTypeForType<T>::metaType = {
/*.dtor=*/ getDtor<T>(),
/*.equals=*/ QEqualityOperatorForType<T>::equals,
/*.lessThan=*/ QLessThanOperatorForType<T>::lessThan,
+ /*.debugStream=*/ QDebugStreamOperatorForType<T>::debugStream,
+ /*.dataStreamOut=*/ QDataStreamOperatorForType<T>::dataStreamOut,
+ /*.dataStreamIn=*/ QDataStreamOperatorForType<T>::dataStreamIn,
/*.legacyRegisterOp=*/ getLegacyRegister<T>()
};
@@ -2809,6 +2785,9 @@ public:
/*.dtor=*/ nullptr,
/*.equals=*/ nullptr,
/*.lessThan=*/ nullptr,
+ /*.debugStream=*/ nullptr,
+ /*.dataStreamOut=*/ nullptr,
+ /*.dataStreamIn=*/ nullptr,
/*.legacyRegisterOp=*/ nullptr
};
};
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index 21a1350fc5..f2641adcd8 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -583,11 +583,9 @@ QByteArray QMimeData::data(const QString &mimeType) const
Note that if you want to use a custom data type in an item view drag and drop
operation, you must register it as a Qt \l{QMetaType}{meta type}, using the
- Q_DECLARE_METATYPE() macro, and implement stream operators for it. The stream
- operators must then be registered with the qRegisterMetaTypeStreamOperators()
- function.
+ Q_DECLARE_METATYPE() macro, and implement stream operators for it.
- \sa hasFormat(), QMetaType, {QMetaType::}{qRegisterMetaTypeStreamOperators()}
+ \sa hasFormat(), QMetaType, {QMetaType::}{Q_DECLARE_METATYPE()}
*/
void QMimeData::setData(const QString &mimeType, const QByteArray &data)
{
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index ff8fd38f0e..a140952559 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2437,7 +2437,8 @@ void QVariant::load(QDataStream &s)
}
// const cast is safe since we operate on a newly constructed variant
- if (!QMetaType::load(s, d.type().id(), const_cast<void *>(constData()))) {
+ void *data = const_cast<void *>(constData());
+ if (!d.type().load(s, data)) {
s.setStatus(QDataStream::ReadCorruptData);
qWarning("QVariant::load: unable to load type %d.", d.type().id());
}
@@ -2512,7 +2513,7 @@ void QVariant::save(QDataStream &s) const
return;
}
- if (!QMetaType::save(s, d.type().id(), constData())) {
+ if (!d.type().save(s, constData())) {
qWarning("QVariant::save: unable to save type '%s' (type id: %d).\n",
QMetaType::typeName(d.type().id()), d.type().id());
Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
@@ -3977,7 +3978,7 @@ QDebug operator<<(QDebug dbg, const QVariant &v)
bool userStream = false;
bool canConvertToString = false;
if (typeId >= QMetaType::User) {
- userStream = QMetaType::debugStream(dbg, constData(v.d), typeId);
+ userStream = v.d.type().debugStream(dbg, constData(v.d));
canConvertToString = v.canConvert<QString>();
}
if (!userStream && canConvertToString)
diff --git a/src/corelib/serialization/qcborcommon.h b/src/corelib/serialization/qcborcommon.h
index 1497da3d2e..f5e38b5a22 100644
--- a/src/corelib/serialization/qcborcommon.h
+++ b/src/corelib/serialization/qcborcommon.h
@@ -133,7 +133,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, QCborKnownTags tg);
Q_CORE_EXPORT QDebug operator<<(QDebug, QCborTag tg);
#endif
-#if !defined(QT_NO_DEBUG_STREAM)
+#if !defined(QT_NO_DATASTREAM)
QDataStream &operator<<(QDataStream &ds, QCborSimpleType st);
QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st);
#endif
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
index e8ef032c24..25c95bc2a5 100644
--- a/src/corelib/tools/qbitarray.h
+++ b/src/corelib/tools/qbitarray.h
@@ -48,8 +48,10 @@ QT_BEGIN_NAMESPACE
class QBitRef;
class Q_CORE_EXPORT QBitArray
{
+#ifndef QT_NO_DATASTREAM
friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &);
friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
+#endif
friend Q_CORE_EXPORT size_t qHash(const QBitArray &key, size_t seed) noexcept;
QByteArray d;