summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobjectdefs.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qobjectdefs.h')
-rw-r--r--src/corelib/kernel/qobjectdefs.h467
1 files changed, 339 insertions, 128 deletions
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index d47c311c18..190901d5d1 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Copyright (C) 2019 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2019 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QOBJECTDEFS_H
#define QOBJECTDEFS_H
@@ -47,6 +11,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qobjectdefs_impl.h>
+#include <QtCore/qtcoreexports.h>
#include <QtCore/qtmetamacros.h>
QT_BEGIN_NAMESPACE
@@ -72,28 +37,31 @@ class QString;
Q_CORE_EXPORT const char *qFlagLocation(const char *method);
#ifndef QT_NO_META_MACROS
-#ifndef QT_NO_DEBUG
-# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
-# ifndef QT_NO_KEYWORDS
-# define METHOD(a) qFlagLocation("0"#a QLOCATION)
+# define QMETHOD_CODE 0 // member type codes
+# define QSLOT_CODE 1
+# define QSIGNAL_CODE 2
+# define QT_PREFIX_CODE(code, a) QT_STRINGIFY(code) #a
+# define QT_STRINGIFY_METHOD(a) QT_PREFIX_CODE(QMETHOD_CODE, a)
+# define QT_STRINGIFY_SLOT(a) QT_PREFIX_CODE(QSLOT_CODE, a)
+# define QT_STRINGIFY_SIGNAL(a) QT_PREFIX_CODE(QSIGNAL_CODE, a)
+# ifndef QT_NO_DEBUG
+# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
+# ifndef QT_NO_KEYWORDS
+# define METHOD(a) qFlagLocation(QT_STRINGIFY_METHOD(a) QLOCATION)
+# endif
+# define SLOT(a) qFlagLocation(QT_STRINGIFY_SLOT(a) QLOCATION)
+# define SIGNAL(a) qFlagLocation(QT_STRINGIFY_SIGNAL(a) QLOCATION)
+# else
+# ifndef QT_NO_KEYWORDS
+# define METHOD(a) QT_STRINGIFY_METHOD(a)
+# endif
+# define SLOT(a) QT_STRINGIFY_SLOT(a)
+# define SIGNAL(a) QT_STRINGIFY_SIGNAL(a)
# endif
-# define SLOT(a) qFlagLocation("1"#a QLOCATION)
-# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
-#else
-# ifndef QT_NO_KEYWORDS
-# define METHOD(a) "0"#a
-# endif
-# define SLOT(a) "1"#a
-# define SIGNAL(a) "2"#a
-#endif
-
-#define QMETHOD_CODE 0 // member type codes
-#define QSLOT_CODE 1
-#define QSIGNAL_CODE 2
#endif // QT_NO_META_MACROS
-#define Q_ARG(type, data) QArgument<type >(#type, data)
-#define Q_RETURN_ARG(type, data) QReturnArgument<type >(#type, data)
+#define Q_ARG(Type, data) QtPrivate::Invoke::argument<Type>(QT_STRINGIFY(Type), data)
+#define Q_RETURN_ARG(Type, data) QtPrivate::Invoke::returnArgument<Type>(QT_STRINGIFY(Type), data)
class QObject;
class QMetaMethod;
@@ -103,6 +71,7 @@ class QMetaClassInfo;
namespace QtPrivate {
class QMetaTypeInterface;
+template<typename T> constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType();
}
struct QMethodRawArguments
@@ -110,6 +79,7 @@ struct QMethodRawArguments
void **arguments;
};
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
class Q_CORE_EXPORT QGenericArgument
{
public:
@@ -157,6 +127,108 @@ public:
: QGenericReturnArgument(aName, static_cast<void *>(&aData))
{}
};
+#endif
+
+struct QMetaMethodArgument
+{
+ const QtPrivate::QMetaTypeInterface *metaType;
+ const char *name;
+ const void *data;
+};
+
+struct QMetaMethodReturnArgument
+{
+ const QtPrivate::QMetaTypeInterface *metaType;
+ const char *name;
+ void *data;
+};
+
+template <typename T>
+struct QTemplatedMetaMethodReturnArgument : QMetaMethodReturnArgument
+{
+ using Type = T;
+};
+
+namespace QtPrivate {
+namespace Invoke {
+#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
+template <typename... Args>
+using AreOldStyleArgs = std::disjunction<std::is_base_of<QGenericArgument, Args>...>;
+
+template <typename T, typename... Args> using IfNotOldStyleArgs =
+ std::enable_if_t<!AreOldStyleArgs<Args...>::value, T>;
+#else
+template <typename T, typename... Args> using IfNotOldStyleArgs = T;
+#endif
+
+template <typename T> inline QMetaMethodArgument argument(const char *name, const T &t)
+{
+ if constexpr ((std::is_lvalue_reference_v<T> && std::is_const_v<std::remove_reference_t<T>>) ||
+ !std::is_reference_v<T>) {
+ return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
+ } else {
+ return { nullptr, name, std::addressof(t) };
+ }
+}
+
+template <typename T>
+inline QTemplatedMetaMethodReturnArgument<T> returnArgument(const char *name, T &t)
+{
+ return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
+}
+
+template <typename T> inline const char *typenameHelper(const T &)
+{
+ return nullptr;
+}
+template <typename T> inline const void *dataHelper(const T &t)
+{
+ return std::addressof(t);
+}
+template <typename T> inline const QMetaTypeInterface *metaTypeHelper(const T &)
+{
+ return qMetaTypeInterfaceForType<T>();
+}
+
+inline const char *typenameHelper(QMetaMethodArgument a)
+{ return a.name; }
+inline const void *dataHelper(QMetaMethodArgument a)
+{ return a.data; }
+inline const QMetaTypeInterface *metaTypeHelper(QMetaMethodArgument a)
+{ return a.metaType; }
+
+inline const char *typenameHelper(const char *) = delete;
+template <typename T> inline const void *dataHelper(const char *) = delete;
+inline const QMetaTypeInterface *metaTypeHelper(const char *) = delete;
+inline const char *typenameHelper(const char16_t *) = delete;
+template <typename T> inline const void *dataHelper(const char16_t *) = delete;
+inline const QMetaTypeInterface *metaTypeHelper(const char16_t *) = delete;
+
+} // namespace QtPrivate::Invoke
+
+template <typename... Args> inline auto invokeMethodHelper(QMetaMethodReturnArgument r, const Args &... arguments)
+{
+ std::array params = { const_cast<const void *>(r.data), Invoke::dataHelper(arguments)... };
+ std::array names = { r.name, Invoke::typenameHelper(arguments)... };
+ std::array types = { r.metaType, Invoke::metaTypeHelper(arguments)... };
+ static_assert(params.size() == types.size());
+ static_assert(params.size() == names.size());
+
+ struct R {
+ decltype(params) parameters;
+ decltype(names) typeNames;
+ decltype(types) metaTypes;
+ constexpr qsizetype parameterCount() const { return qsizetype(parameters.size()); }
+ };
+ return R { params, names, types };
+}
+} // namespace QtPrivate
+
+template <typename T> void qReturnArg(const T &&) = delete;
+template <typename T> inline QTemplatedMetaMethodReturnArgument<T> qReturnArg(T &data)
+{
+ return QtPrivate::Invoke::returnArgument(nullptr, data);
+}
struct Q_CORE_EXPORT QMetaObject
{
@@ -165,13 +237,16 @@ struct Q_CORE_EXPORT QMetaObject
const QMetaObject *superClass() const;
bool inherits(const QMetaObject *metaObject) const noexcept;
- QObject *cast(QObject *obj) const;
+ QObject *cast(QObject *obj) const
+ { return const_cast<QObject *>(cast(const_cast<const QObject *>(obj))); }
const QObject *cast(const QObject *obj) const;
-#if !defined(QT_NO_TRANSLATION) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_TRANSLATION) || defined(Q_QDOC)
QString tr(const char *s, const char *c, int n = -1) const;
#endif // QT_NO_TRANSLATION
+ QMetaType metaType() const;
+
int methodOffset() const;
int enumeratorOffset() const;
int propertyOffset() const;
@@ -188,6 +263,7 @@ struct Q_CORE_EXPORT QMetaObject
int indexOfSignal(const char *signal) const;
int indexOfSlot(const char *slot) const;
int indexOfEnumerator(const char *name) const;
+
int indexOfProperty(const char *name) const;
int indexOfClassInfo(const char *name) const;
@@ -221,6 +297,7 @@ struct Q_CORE_EXPORT QMetaObject
static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv);
+#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
static bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType,
QGenericReturnArgument ret,
@@ -254,7 +331,7 @@ struct Q_CORE_EXPORT QMetaObject
static inline bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType type,
- QGenericArgument val0 = QGenericArgument(nullptr),
+ QGenericArgument val0,
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -270,7 +347,7 @@ struct Q_CORE_EXPORT QMetaObject
}
static inline bool invokeMethod(QObject *obj, const char *member,
- QGenericArgument val0 = QGenericArgument(nullptr),
+ QGenericArgument val0,
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -284,89 +361,162 @@ struct Q_CORE_EXPORT QMetaObject
return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0,
val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
+#endif // Qt < 7.0
+
+ template <typename ReturnArg, typename... Args> static
+#ifdef Q_QDOC
+ bool
+#else
+ QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
+#endif
+ invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c,
+ QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... arguments)
+ {
+ auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
+ return invokeMethodImpl(obj, member, c, h.parameterCount(), h.parameters.data(),
+ h.typeNames.data(), h.metaTypes.data());
+ }
+
+ template <typename... Args> static
+#ifdef Q_QDOC
+ bool
+#else
+ QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
+#endif
+ invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c, Args &&... arguments)
+ {
+ QTemplatedMetaMethodReturnArgument<void> r = {};
+ return invokeMethod(obj, member, c, r, std::forward<Args>(arguments)...);
+ }
+
+ template <typename ReturnArg, typename... Args> static
+#ifdef Q_QDOC
+ bool
+#else
+ QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
+#endif
+ invokeMethod(QObject *obj, const char *member, QTemplatedMetaMethodReturnArgument<ReturnArg> r,
+ Args &&... arguments)
+ {
+ return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
+ }
+
+ template <typename... Args> static
+#ifdef Q_QDOC
+ bool
+#else
+ QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
+#endif
+ invokeMethod(QObject *obj, const char *member, Args &&... arguments)
+ {
+ QTemplatedMetaMethodReturnArgument<void> r = {};
+ return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
+ }
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
template<typename Functor, typename FunctorReturnType>
- static bool invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr);
+ static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr);
template<typename Functor, typename FunctorReturnType>
- static bool invokeMethod(QObject *context, Functor function, FunctorReturnType *ret);
+ static bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret);
+
+ template<typename Functor, typename FunctorReturnType, typename... Args>
+ static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
+ template<typename Functor, typename FunctorReturnType, typename... Args>
+ static bool invokeMethod(QObject *context, Functor &&function, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
+ template<typename Functor, typename... Args>
+ static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, Args &&...arguments);
+ template<typename Functor, typename... Args>
+ static bool invokeMethod(QObject *context, Functor &&function, Args &&...arguments);
#else
-
- // invokeMethod() for member function pointer
template <typename Func>
- static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
- && !std::is_convertible<Func, const char*>::value
- && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
- invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object,
- Func function,
- Qt::ConnectionType type = Qt::AutoConnection,
- typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr)
+ static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
+ QtPrivate::Invoke::AreOldStyleArgs<Func>>,
+ bool>
+ invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
+ Func &&function, Qt::ConnectionType type,
+ typename QtPrivate::Callable<Func>::ReturnType *ret)
{
- return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), type, ret);
+ using R = typename QtPrivate::Callable<Func>::ReturnType;
+ const auto getReturnArg = [ret]() -> QTemplatedMetaMethodReturnArgument<R> {
+ if constexpr (std::is_void_v<R>)
+ return {};
+ else
+ return ret ? qReturnArg(*ret) : QTemplatedMetaMethodReturnArgument<R>{};
+ };
+ return invokeMethod(object, std::forward<Func>(function), type, getReturnArg());
}
-
template <typename Func>
- static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
- && !std::is_convertible<Func, const char*>::value
- && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
- invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object,
- Func function,
- typename QtPrivate::FunctionPointer<Func>::ReturnType *ret)
+ static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
+ QtPrivate::Invoke::AreOldStyleArgs<Func>>,
+ bool>
+ invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
+ Func &&function, typename QtPrivate::Callable<Func>::ReturnType *ret)
{
- return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), Qt::AutoConnection, ret);
+ return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret);
}
- // invokeMethod() for function pointer (not member)
- template <typename Func>
- static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
- && !std::is_convertible<Func, const char*>::value
- && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
- invokeMethod(QObject *context, Func function,
- Qt::ConnectionType type = Qt::AutoConnection,
- typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr)
+ template <typename Func, typename... Args>
+ static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
+ QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
+ bool>
+ invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
+ Func &&function, Qt::ConnectionType type,
+ QTemplatedMetaMethodReturnArgument<
+ typename QtPrivate::Callable<Func, Args...>::ReturnType>
+ ret,
+ Args &&...args)
{
- return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), type, ret);
+ return invokeMethodCallableHelper(object, std::forward<Func>(function), type, ret,
+ std::forward<Args>(args)...);
}
- template <typename Func>
- static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
- && !std::is_convertible<Func, const char*>::value
- && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type
- invokeMethod(QObject *context, Func function,
- typename QtPrivate::FunctionPointer<Func>::ReturnType *ret)
+ template <typename Func, typename... Args>
+ static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
+ QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
+ bool>
+ invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
+ Func &&function, Qt::ConnectionType type, Args &&...args)
{
- return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), Qt::AutoConnection, ret);
+ using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
+ QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
+ nullptr };
+ return invokeMethod(object, std::forward<Func>(function), type, r,
+ std::forward<Args>(args)...);
}
- // invokeMethod() for Functor
- template <typename Func>
- static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
- && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
- && !std::is_convertible<Func, const char*>::value, bool>::type
- invokeMethod(QObject *context, Func function,
- Qt::ConnectionType type = Qt::AutoConnection, decltype(function()) *ret = nullptr)
+ template <typename Func, typename... Args>
+ static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
+ QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
+ bool>
+ invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
+ Func &&function,
+ QTemplatedMetaMethodReturnArgument<
+ typename QtPrivate::Callable<Func, Args...>::ReturnType>
+ ret,
+ Args &&...args)
{
- return invokeMethodImpl(context,
- new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
- type,
- ret);
+ return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret,
+ std::forward<Args>(args)...);
}
- template <typename Func>
- static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
- && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
- && !std::is_convertible<Func, const char*>::value, bool>::type
- invokeMethod(QObject *context, Func function, decltype(function()) *ret)
+ template <typename Func, typename... Args>
+ static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
+ QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
+ bool>
+ invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
+ Func &&function, Args &&...args)
{
- return invokeMethodImpl(context,
- new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
- Qt::AutoConnection,
- ret);
+ using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
+ QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
+ nullptr };
+ return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, r,
+ std::forward<Args>(args)...);
}
#endif
- QObject *newInstance(QGenericArgument val0 = QGenericArgument(nullptr),
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ QObject *newInstance(QGenericArgument val0,
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -376,6 +526,20 @@ struct Q_CORE_EXPORT QMetaObject
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument()) const;
+#endif
+
+ template <typename... Args>
+#ifdef Q_QDOC
+ QObject *
+#else
+ QtPrivate::Invoke::IfNotOldStyleArgs<QObject *, Args...>
+#endif
+ newInstance(Args &&... arguments) const
+ {
+ auto h = QtPrivate::invokeMethodHelper(QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
+ return newInstanceImpl(this, h.parameterCount(), h.parameters.data(),
+ h.typeNames.data(), h.metaTypes.data());
+ }
enum Call {
InvokeMetaMethod,
@@ -386,8 +550,9 @@ struct Q_CORE_EXPORT QMetaObject
IndexOfMethod,
RegisterPropertyMetaType,
RegisterMethodArgumentMetaType,
- RegisterQPropertyObserver,
- SetQPropertyBinding
+ BindableProperty,
+ CustomCall,
+ ConstructInPlace,
};
int static_metacall(Call, int, void **) const;
@@ -399,6 +564,7 @@ struct Q_CORE_EXPORT QMetaObject
}
struct SuperData {
+ using Getter = const QMetaObject *(*)();
const QMetaObject *direct;
SuperData() = default;
constexpr SuperData(std::nullptr_t) : direct(nullptr) {}
@@ -407,7 +573,6 @@ struct Q_CORE_EXPORT QMetaObject
constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); }
#ifdef QT_NO_DATA_RELOCATION
- using Getter = const QMetaObject *(*)();
Getter indirect = nullptr;
constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {}
constexpr operator const QMetaObject *() const
@@ -415,6 +580,7 @@ struct Q_CORE_EXPORT QMetaObject
template <const QMetaObject &MO> static constexpr SuperData link()
{ return SuperData(QMetaObject::staticMetaObject<MO>); }
#else
+ constexpr SuperData(Getter g) : direct(g()) {}
constexpr operator const QMetaObject *() const
{ return direct; }
template <const QMetaObject &MO> static constexpr SuperData link()
@@ -429,13 +595,51 @@ struct Q_CORE_EXPORT QMetaObject
typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
StaticMetacallFunction static_metacall;
const SuperData *relatedMetaObjects;
- QtPrivate::QMetaTypeInterface *const *metaTypes;
+ const QtPrivate::QMetaTypeInterface *const *metaTypes;
void *extradata; //reserved for future use
} d;
private:
+ // Just need to have this here with a separate name so the other inline
+ // functions can call this without any ambiguity
+ template <typename Func, typename... Args>
+ static bool
+ invokeMethodCallableHelper(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
+ Func &&function, Qt::ConnectionType type, const QMetaMethodReturnArgument &ret,
+ Args &&...args)
+ {
+ using Callable = QtPrivate::Callable<Func, Args...>;
+ using ExpectedArguments = typename Callable::Arguments;
+ static_assert(sizeof...(Args) <= ExpectedArguments::size, "Too many arguments");
+ using ActualArguments = QtPrivate::List<Args...>;
+ static_assert(QtPrivate::CheckCompatibleArguments<ActualArguments,
+ ExpectedArguments>::value,
+ "Incompatible arguments");
+
+ auto h = QtPrivate::invokeMethodHelper(ret, std::forward<Args>(args)...);
+
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
+ auto callable = new QtPrivate::QCallableObject<std::decay_t<Func>, ActualArguments,
+ typename Callable::ReturnType>(std::forward<Func>(function));
+ return invokeMethodImpl(object, callable, type, h.parameterCount(), h.parameters.data(),
+ h.typeNames.data(), h.metaTypes.data());
+ }
+
+ static bool invokeMethodImpl(QObject *object, const char *member, Qt::ConnectionType type,
+ qsizetype parameterCount, const void *const *parameters, const char *const *names,
+ const QtPrivate::QMetaTypeInterface * const *metaTypes);
+ static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slotObj,
+ Qt::ConnectionType type, qsizetype parameterCount,
+ const void *const *params, const char *const *names,
+ const QtPrivate::QMetaTypeInterface *const *metaTypes);
+#if QT_CORE_REMOVED_SINCE(6, 7)
static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret);
+#endif
+ static QObject *newInstanceImpl(const QMetaObject *mobj, qsizetype parameterCount,
+ const void **parameters, const char **typeNames,
+ const QtPrivate::QMetaTypeInterface **metaTypes);
friend class QTimer;
+ friend class QChronoTimer;
};
class Q_CORE_EXPORT QMetaObject::Connection {
@@ -453,20 +657,27 @@ public:
#ifdef Q_QDOC
operator bool() const;
#else
+ // still using the restricted bool trick here, in order to support
+ // code using copy-init (e.g. `bool ok = connect(...)`)
typedef void *Connection::*RestrictedBool;
operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : nullptr; }
#endif
- Connection(Connection &&o) noexcept : d_ptr(o.d_ptr) { o.d_ptr = nullptr; }
- Connection &operator=(Connection &&other) noexcept
- { qSwap(d_ptr, other.d_ptr); return *this; }
+ Connection(Connection &&other) noexcept : d_ptr(std::exchange(other.d_ptr, nullptr)) {}
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Connection)
+ void swap(Connection &other) noexcept { qt_ptr_swap(d_ptr, other.d_ptr); }
};
+inline void swap(QMetaObject::Connection &lhs, QMetaObject::Connection &rhs) noexcept
+{
+ lhs.swap(rhs);
+}
+
inline const QMetaObject *QMetaObject::superClass() const
{ return d.superdata; }
namespace QtPrivate {
- /* Trait that tells is a the Object has a Q_OBJECT macro */
+ // Trait that tells if a QObject has a Q_OBJECT macro
template <typename Object> struct HasQ_OBJECT_Macro {
template <typename T>
static char test(int (T::*)(QMetaObject::Call, int, void **));