Make qReturnArg return a type templated with the return type
This way we can make check verify that the passed-in pointer is correct at compile time. Doesn't do this in this patch because all current uses are in the string-based overloads, but we'll use it in a later patch which adds new invokeMethod overloads for the functor-based API. Change-Id: I30186adc9d0b67c7ca337deb35c2c34661e50261 Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
306d32fdd3
commit
777a1ed191
@ -1426,8 +1426,8 @@ printMethodNotFoundWarning(const QMetaObject *meta, QLatin1StringView name, qsiz
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template <typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QMetaMethodReturnArgument r, Args &&... args)
|
\fn template <typename ReturnArg, typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... args)
|
||||||
\fn template <typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, QMetaMethodReturnArgument r, Args &&... args)
|
\fn template <typename ReturnArg, typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... args)
|
||||||
\fn template <typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, Args &&... args)
|
\fn template <typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, Args &&... args)
|
||||||
\fn template <typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, Args &&... args)
|
\fn template <typename... Args> bool QMetaObject::invokeMethod(QObject *obj, const char *member, Args &&... args)
|
||||||
\since 6.5
|
\since 6.5
|
||||||
@ -1437,11 +1437,12 @@ printMethodNotFoundWarning(const QMetaObject *meta, QLatin1StringView name, qsiz
|
|||||||
obj. Returns \c true if the member could be invoked. Returns \c false
|
obj. Returns \c true if the member could be invoked. Returns \c false
|
||||||
if there is no such member or the parameters did not match.
|
if there is no such member or the parameters did not match.
|
||||||
|
|
||||||
For the overloads with a QMetaMethodReturnArgument parameter, the return
|
For the overloads with a QTemplatedMetaMethodReturnArgument parameter, the
|
||||||
value of the \a member function call is placed in \a ret. For the overloads
|
return value of the \a member function call is placed in \a ret. For the
|
||||||
without such a member, the return value of the called function (if any)
|
overloads without such a member, the return value of the called function
|
||||||
will be discarded. QMetaMethodReturnArgument is an internal type you should
|
(if any) will be discarded. QTemplatedMetaMethodReturnArgument is an
|
||||||
not use directly. Instead, use the qReturnArg() function.
|
internal type you should not use directly. Instead, use the qReturnArg()
|
||||||
|
function.
|
||||||
|
|
||||||
The overloads with a Qt::ConnectionType \a type parameter allow explicitly
|
The overloads with a Qt::ConnectionType \a type parameter allow explicitly
|
||||||
selecting whether the invocation will be synchronous or not:
|
selecting whether the invocation will be synchronous or not:
|
||||||
@ -2379,20 +2380,21 @@ QMetaMethod QMetaMethod::fromSignalImpl(const QMetaObject *metaObject, void **si
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template <typename... Args> bool QMetaMethod::invoke(QObject *obj, Qt::ConnectionType type, QMetaMethodReturnArgument ret, Args &&... arguments) const
|
\fn template <typename ReturnArg, typename... Args> bool QMetaMethod::invoke(QObject *obj, Qt::ConnectionType type, QTemplatedMetaMethodReturnArgument<ReturnArg> ret, Args &&... arguments) const
|
||||||
\fn template <typename... Args> bool QMetaMethod::invoke(QObject *obj, Qt::ConnectionType type, Args &&... arguments) const
|
\fn template <typename... Args> bool QMetaMethod::invoke(QObject *obj, Qt::ConnectionType type, Args &&... arguments) const
|
||||||
\fn template <typename... Args> bool QMetaMethod::invoke(QObject *obj, QMetaMethodReturnArgument ret, Args &&... arguments) const
|
\fn template <typename ReturnArg, typename... Args> bool QMetaMethod::invoke(QObject *obj, QTemplatedMetaMethodReturnArgument<ReturnArg> ret, Args &&... arguments) const
|
||||||
\fn template <typename... Args> bool QMetaMethod::invoke(QObject *obj, Args &&... arguments) const
|
\fn template <typename... Args> bool QMetaMethod::invoke(QObject *obj, Args &&... arguments) const
|
||||||
\since 6.5
|
\since 6.5
|
||||||
|
|
||||||
Invokes this method on the object \a object. Returns \c true if the member could be invoked.
|
Invokes this method on the object \a object. Returns \c true if the member could be invoked.
|
||||||
Returns \c false if there is no such member or the parameters did not match.
|
Returns \c false if there is no such member or the parameters did not match.
|
||||||
|
|
||||||
For the overloads with a QMetaMethodReturnArgument parameter, the return
|
For the overloads with a QTemplatedMetaMethodReturnArgument parameter, the
|
||||||
value of the \a member function call is placed in \a ret. For the overloads
|
return value of the \a member function call is placed in \a ret. For the
|
||||||
without such a member, the return value of the called function (if any)
|
overloads without such a member, the return value of the called function
|
||||||
will be discarded. QMetaMethodReturnArgument is an internal type you should
|
(if any) will be discarded. QTemplatedMetaMethodReturnArgument is an
|
||||||
not use directly. Instead, use the qReturnArg() function.
|
internal type you should not use directly. Instead, use the qReturnArg()
|
||||||
|
function.
|
||||||
|
|
||||||
The overloads with a Qt::ConnectionType \a type parameter allow explicitly
|
The overloads with a Qt::ConnectionType \a type parameter allow explicitly
|
||||||
selecting whether the invocation will be synchronous or not:
|
selecting whether the invocation will be synchronous or not:
|
||||||
@ -2819,7 +2821,7 @@ auto QMetaMethodInvoker::invokeImpl(QMetaMethod self, void *target,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template <typename... Args> bool QMetaMethod::invokeOnGadget(void *gadget, QMetaMethodReturnArgument ret, Args &&... arguments) const
|
\fn template <typename ReturnArg, typename... Args> bool QMetaMethod::invokeOnGadget(void *gadget, QTemplatedMetaMethodReturnArgument<ReturnArg> ret, Args &&... arguments) const
|
||||||
\fn template <typename... Args> bool QMetaMethod::invokeOnGadget(void *gadget, Args &&... arguments) const
|
\fn template <typename... Args> bool QMetaMethod::invokeOnGadget(void *gadget, Args &&... arguments) const
|
||||||
\since 6.5
|
\since 6.5
|
||||||
|
|
||||||
@ -2830,11 +2832,11 @@ auto QMetaMethodInvoker::invokeImpl(QMetaMethod self, void *target,
|
|||||||
|
|
||||||
The invocation is always synchronous.
|
The invocation is always synchronous.
|
||||||
|
|
||||||
For the overload with a QMetaMethodReturnArgument parameter, the return
|
For the overload with a QTemplatedMetaMethodReturnArgument parameter, the
|
||||||
value of the \a member function call is placed in \a ret. For the overload
|
return value of the \a member function call is placed in \a ret. For the
|
||||||
without it, the return value of the called function (if any) will be
|
overload without it, the return value of the called function (if any) will
|
||||||
discarded. QMetaMethodReturnArgument is an internal type you should not use
|
be discarded. QTemplatedMetaMethodReturnArgument is an internal type you
|
||||||
directly. Instead, use the qReturnArg() function.
|
should not use directly. Instead, use the qReturnArg() function.
|
||||||
|
|
||||||
\warning this method will not test the validity of the arguments: \a gadget
|
\warning this method will not test the validity of the arguments: \a gadget
|
||||||
must be an instance of the class of the QMetaObject of which this QMetaMethod
|
must be an instance of the class of the QMetaObject of which this QMetaMethod
|
||||||
|
@ -135,13 +135,13 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename ReturnArg, typename... Args>
|
||||||
#ifdef Q_QDOC
|
#ifdef Q_QDOC
|
||||||
bool
|
bool
|
||||||
#else
|
#else
|
||||||
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
||||||
#endif
|
#endif
|
||||||
invoke(QObject *obj, Qt::ConnectionType c, QMetaMethodReturnArgument r,
|
invoke(QObject *obj, Qt::ConnectionType c, QTemplatedMetaMethodReturnArgument<ReturnArg> r,
|
||||||
Args &&... arguments) const
|
Args &&... arguments) const
|
||||||
{
|
{
|
||||||
auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
|
auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
|
||||||
@ -157,16 +157,16 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
invoke(QObject *obj, Qt::ConnectionType c, Args &&... arguments) const
|
invoke(QObject *obj, Qt::ConnectionType c, Args &&... arguments) const
|
||||||
{
|
{
|
||||||
return invoke(obj, c, QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
|
return invoke(obj, c, QTemplatedMetaMethodReturnArgument<void>{}, std::forward<Args>(arguments)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename ReturnArg, typename... Args>
|
||||||
#ifdef Q_QDOC
|
#ifdef Q_QDOC
|
||||||
bool
|
bool
|
||||||
#else
|
#else
|
||||||
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
||||||
#endif
|
#endif
|
||||||
invoke(QObject *obj, QMetaMethodReturnArgument r, Args &&... arguments) const
|
invoke(QObject *obj, QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... arguments) const
|
||||||
{
|
{
|
||||||
return invoke(obj, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
|
return invoke(obj, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
|
||||||
}
|
}
|
||||||
@ -182,13 +182,13 @@ public:
|
|||||||
return invoke(obj, Qt::AutoConnection, std::forward<Args>(arguments)...);
|
return invoke(obj, Qt::AutoConnection, std::forward<Args>(arguments)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename ReturnArg, typename... Args>
|
||||||
#ifdef Q_QDOC
|
#ifdef Q_QDOC
|
||||||
bool
|
bool
|
||||||
#else
|
#else
|
||||||
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
||||||
#endif
|
#endif
|
||||||
invokeOnGadget(void *gadget, QMetaMethodReturnArgument r, Args &&... arguments) const
|
invokeOnGadget(void *gadget, QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... arguments) const
|
||||||
{
|
{
|
||||||
auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
|
auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
|
||||||
return invokeImpl(*this, gadget, Qt::ConnectionType(-1), h.parameterCount(),
|
return invokeImpl(*this, gadget, Qt::ConnectionType(-1), h.parameterCount(),
|
||||||
@ -203,7 +203,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
invokeOnGadget(void *gadget, Args &&... arguments) const
|
invokeOnGadget(void *gadget, Args &&... arguments) const
|
||||||
{
|
{
|
||||||
return invokeOnGadget(gadget, QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
|
return invokeOnGadget(gadget, QTemplatedMetaMethodReturnArgument<void>{}, std::forward<Args>(arguments)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isValid() const { return mobj != nullptr; }
|
inline bool isValid() const { return mobj != nullptr; }
|
||||||
|
@ -142,6 +142,12 @@ struct QMetaMethodReturnArgument
|
|||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct QTemplatedMetaMethodReturnArgument : QMetaMethodReturnArgument
|
||||||
|
{
|
||||||
|
using Type = T;
|
||||||
|
};
|
||||||
|
|
||||||
namespace QtPrivate {
|
namespace QtPrivate {
|
||||||
namespace Invoke {
|
namespace Invoke {
|
||||||
#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
|
#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
|
||||||
@ -164,7 +170,8 @@ template <typename T> inline QMetaMethodArgument argument(const char *name, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline QMetaMethodReturnArgument returnArgument(const char *name, T &t)
|
template <typename T>
|
||||||
|
inline QTemplatedMetaMethodReturnArgument<T> returnArgument(const char *name, T &t)
|
||||||
{
|
{
|
||||||
return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
|
return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
|
||||||
}
|
}
|
||||||
@ -217,7 +224,7 @@ template <typename... Args> inline auto invokeMethodHelper(QMetaMethodReturnArgu
|
|||||||
} // namespace QtPrivate
|
} // namespace QtPrivate
|
||||||
|
|
||||||
template <typename T> void qReturnArg(const T &&) = delete;
|
template <typename T> void qReturnArg(const T &&) = delete;
|
||||||
template <typename T> inline QMetaMethodReturnArgument qReturnArg(T &data)
|
template <typename T> inline QTemplatedMetaMethodReturnArgument<T> qReturnArg(T &data)
|
||||||
{
|
{
|
||||||
return QtPrivate::Invoke::returnArgument(nullptr, data);
|
return QtPrivate::Invoke::returnArgument(nullptr, data);
|
||||||
}
|
}
|
||||||
@ -354,14 +361,14 @@ struct Q_CORE_EXPORT QMetaObject
|
|||||||
}
|
}
|
||||||
#endif // Qt < 7.0
|
#endif // Qt < 7.0
|
||||||
|
|
||||||
template <typename... Args> static
|
template <typename ReturnArg, typename... Args> static
|
||||||
#ifdef Q_QDOC
|
#ifdef Q_QDOC
|
||||||
bool
|
bool
|
||||||
#else
|
#else
|
||||||
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
||||||
#endif
|
#endif
|
||||||
invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c,
|
invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c,
|
||||||
QMetaMethodReturnArgument r, Args &&... arguments)
|
QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... arguments)
|
||||||
{
|
{
|
||||||
auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
|
auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
|
||||||
return invokeMethodImpl(obj, member, c, h.parameterCount(), h.parameters.data(),
|
return invokeMethodImpl(obj, member, c, h.parameterCount(), h.parameters.data(),
|
||||||
@ -376,17 +383,17 @@ struct Q_CORE_EXPORT QMetaObject
|
|||||||
#endif
|
#endif
|
||||||
invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c, Args &&... arguments)
|
invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c, Args &&... arguments)
|
||||||
{
|
{
|
||||||
QMetaMethodReturnArgument r = {};
|
QTemplatedMetaMethodReturnArgument<void> r = {};
|
||||||
return invokeMethod(obj, member, c, r, std::forward<Args>(arguments)...);
|
return invokeMethod(obj, member, c, r, std::forward<Args>(arguments)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args> static
|
template <typename ReturnArg, typename... Args> static
|
||||||
#ifdef Q_QDOC
|
#ifdef Q_QDOC
|
||||||
bool
|
bool
|
||||||
#else
|
#else
|
||||||
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
|
||||||
#endif
|
#endif
|
||||||
invokeMethod(QObject *obj, const char *member, QMetaMethodReturnArgument r,
|
invokeMethod(QObject *obj, const char *member, QTemplatedMetaMethodReturnArgument<ReturnArg> r,
|
||||||
Args &&... arguments)
|
Args &&... arguments)
|
||||||
{
|
{
|
||||||
return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
|
return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
|
||||||
@ -400,7 +407,7 @@ struct Q_CORE_EXPORT QMetaObject
|
|||||||
#endif
|
#endif
|
||||||
invokeMethod(QObject *obj, const char *member, Args &&... arguments)
|
invokeMethod(QObject *obj, const char *member, Args &&... arguments)
|
||||||
{
|
{
|
||||||
QMetaMethodReturnArgument r = {};
|
QTemplatedMetaMethodReturnArgument<void> r = {};
|
||||||
return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
|
return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user