summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-07-19 12:31:07 -0700
committerThiago Macieira <thiago.macieira@intel.com>2022-07-26 20:12:30 -0700
commit74fac865cf7c55d3afba1043072ba6cc932d161d (patch)
tree4bb096785a07fb5986c2b1311de66fbd1a32c349 /src/corelib/kernel
parentb1d9331c156b7ff5c724600eee21ac50f4565868 (diff)
QMetaType: add registerType() and qRegisterMetaType(QMetaType)
This also rewrites QMetaType::id() on top of the helper, with the benefit of calling a member static function, so QMetaType doesn't need to be spilled onto the stack. In some upcoming changes I need to ensure that QMetaTypes are registered so they can be found by name and I'd like to have a dedicated function name for that, instead of calling .id(). Since I needed to add docs for the new function, I've updated for the old one too. [ChangeLog][QMetaType] Added QMetaType::registerType() and an overload of qRegisterMetaType() taking QMetaType (the two functions do the same thing). These two functions ensure a given QMetaType is registered with the Qt global registry, so they can be found by name later. Using qRegisterMetaType<T>() also accomplishes the same thing, but is slightly better for completely generic code because it will avoid emitting the registration for built-in types. Change-Id: I3859764fed084846bcb0fffd170351d606034c22 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qmetatype.cpp68
-rw-r--r--src/corelib/kernel/qmetatype.h36
2 files changed, 80 insertions, 24 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 4aed2edebb..ea7cd4a0c9 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -495,19 +495,28 @@ bool QMetaType::isRegistered() const
\fn int QMetaType::id() const
\since 5.13
- Returns id type hold by this QMetatype instance.
+ Returns id type held by this QMetatype instance.
*/
/*!
+ \fn void QMetaType::registerType() const
+ \since 6.5
+
+ Registers this QMetaType with the type registry so it can be found by name,
+ using QMetaType::fromName().
+
+ \sa qRegisterMetaType()
+ */
+/*!
\internal
- The slowpath of id(). Precondition: d_ptr != nullptr
-*/
-int QMetaType::idHelper() const
+ Out-of-line path for registerType() and slow path id().
+ */
+int QMetaType::registerHelper(const QtPrivate::QMetaTypeInterface *iface)
{
- Q_ASSERT(d_ptr);
+ Q_ASSERT(iface);
auto reg = customTypeRegistry();
if (reg) {
- return reg->registerCustomType(d_ptr);
+ return reg->registerCustomType(iface);
}
return 0;
}
@@ -2890,6 +2899,7 @@ QMetaType QMetaType::fromName(QByteArrayView typeName)
/*!
\fn int qRegisterMetaType(const char *typeName)
\relates QMetaType
+ \obsolete
\threadsafe
Registers the type name \a typeName for the type \c{T}. Returns
@@ -2926,8 +2936,7 @@ QMetaType QMetaType::fromName(QByteArrayView typeName)
\threadsafe
\since 4.2
- Call this function to register the type \c T. \c T must be declared with
- Q_DECLARE_METATYPE(). Returns the meta type Id.
+ Call this function to register the type \c T. Returns the meta type Id.
Example:
@@ -2938,23 +2947,46 @@ QMetaType QMetaType::fromName(QByteArrayView typeName)
pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
to register pointers to forward declared types.
- After a type has been registered, you can create and destroy
- objects of that type dynamically at run-time.
+ To use the type \c T in QMetaType, QVariant, or with the
+ QObject::property() API, registration is not necessary.
- To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
- sufficient. To use the type \c T in queued signal and slot connections,
- \c{qRegisterMetaType<T>()} must be called before the first connection
- is established.
+ To use the type \c T in queued signal and slot connections,
+ \c{qRegisterMetaType<T>()} must be called before the first connection is
+ established. That is typically done in the constructor of the class that
+ uses \c T, or in the \c{main()} function.
- Also, to use type \c T with the QObject::property() API,
- \c{qRegisterMetaType<T>()} must be called before it is used, typically
- in the constructor of the class that uses \c T, or in the \c{main()}
- function.
+ After a type has been registered, it can be found by its name using
+ QMetaType::fromName().
\sa Q_DECLARE_METATYPE()
*/
/*!
+ \fn int qRegisterMetaType(QMetaType meta)
+ \relates QMetaType
+ \threadsafe
+ \since 6.5
+
+ Registers the meta type \a meta and returns its type Id.
+
+ This function requires that \c{T} is a fully defined type at the point
+ where the function is called. For pointer types, it also requires that the
+ pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
+ to register pointers to forward declared types.
+
+ To use the type \c T in QMetaType, QVariant, or with the
+ QObject::property() API, registration is not necessary.
+
+ To use the type \c T in queued signal and slot connections,
+ \c{qRegisterMetaType<T>()} must be called before the first connection is
+ established. That is typically done in the constructor of the class that
+ uses \c T, or in the \c{main()} function.
+
+ After a type has been registered, it can be found by its name using
+ QMetaType::fromName().
+ */
+
+/*!
\fn int qMetaTypeId()
\relates QMetaType
\threadsafe
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index f4d3c5b54d..e9599af5bb 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -426,6 +426,11 @@ public:
bool isValid() const;
bool isRegistered() const;
+ void registerType() const
+ {
+ // "register" is a reserved keyword
+ registerHelper();
+ }
#if QT_CORE_REMOVED_SINCE(6, 1) || defined(Q_QDOC)
int id() const;
#else
@@ -434,12 +439,7 @@ public:
int id(int = 0) const
{
// keep in sync with the version in removed_api.cpp
- if (d_ptr) {
- if (int id = d_ptr->typeId.loadRelaxed())
- return id;
- return idHelper();
- }
- return 0;
+ return registerHelper();
}
#endif
constexpr qsizetype sizeOf() const;
@@ -722,7 +722,23 @@ public:
const QtPrivate::QMetaTypeInterface *iface() const { return d_ptr; }
private:
+#if QT_CORE_REMOVED_SINCE(6, 5)
int idHelper() const;
+#endif
+ static int registerHelper(const QtPrivate::QMetaTypeInterface *iface);
+ int registerHelper() const
+ {
+ // keep in sync with the QMetaType::id() version in removed_api.cpp
+ if (d_ptr) {
+ if (int id = d_ptr->typeId.loadRelaxed())
+ return id;
+ return registerHelper(d_ptr);
+ }
+ return 0;
+ }
+
+ friend int qRegisterMetaType(QMetaType meta);
+
friend class QVariant;
const QtPrivate::QMetaTypeInterface *d_ptr = nullptr;
};
@@ -1285,6 +1301,9 @@ template <typename T>
inline constexpr int qMetaTypeId()
{
if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
+ // this has the same result as the below code, but avoids asking the
+ // compiler to load a global variable whose value we know at compile
+ // time
return QMetaTypeId2<T>::MetaType;
} else {
return QMetaType::fromType<T>().id();
@@ -1298,6 +1317,11 @@ inline constexpr int qRegisterMetaType()
return id;
}
+inline int qRegisterMetaType(QMetaType meta)
+{
+ return meta.registerHelper();
+}
+
#ifndef QT_NO_QOBJECT
template <typename T>
struct QMetaTypeIdQObject<T*, QMetaType::PointerToQObject>