summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobjectdefs_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qobjectdefs_impl.h')
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h33
1 files changed, 29 insertions, 4 deletions
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index a3068e1712..da9d0f6390 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -50,6 +50,7 @@
QT_BEGIN_NAMESPACE
class QObject;
+class QObjectPrivate;
namespace QtPrivate {
template <typename T> struct RemoveRef { typedef T Type; };
@@ -139,6 +140,22 @@ namespace QtPrivate {
template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
+ template<typename ObjPrivate> inline void assertObjectType(QObjectPrivate *d);
+ template<typename Obj> inline void assertObjectType(QObject *o)
+ {
+ // ensure all three compile
+ [[maybe_unused]] auto staticcast = [](QObject *obj) { return static_cast<Obj *>(obj); };
+ [[maybe_unused]] auto qobjcast = [](QObject *obj) { return Obj::staticMetaObject.cast(obj); };
+#ifdef __cpp_rtti
+ [[maybe_unused]] auto dyncast = [](QObject *obj) { return dynamic_cast<Obj *>(obj); };
+ auto cast = dyncast;
+#else
+ auto cast = qobjcast;
+#endif
+ Q_ASSERT_X(cast(o), Obj::staticMetaObject.className(),
+ "Called object is not of the correct type (class destructor may have already run)");
+ }
+
template <typename, typename, typename, typename> struct FunctorCall;
template <int... II, typename... SignalArgs, typename R, typename Function>
struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, Function> {
@@ -148,25 +165,33 @@ namespace QtPrivate {
};
template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
- static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) {
+ static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg)
+ {
+ assertObjectType<Obj>(o);
(o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const> {
- static void call(SlotRet (Obj::*f)(SlotArgs...) const, Obj *o, void **arg) {
+ static void call(SlotRet (Obj::*f)(SlotArgs...) const, Obj *o, void **arg)
+ {
+ assertObjectType<Obj>(o);
(o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) noexcept> {
- static void call(SlotRet (Obj::*f)(SlotArgs...) noexcept, Obj *o, void **arg) {
+ static void call(SlotRet (Obj::*f)(SlotArgs...) noexcept, Obj *o, void **arg)
+ {
+ assertObjectType<Obj>(o);
(o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const noexcept> {
- static void call(SlotRet (Obj::*f)(SlotArgs...) const noexcept, Obj *o, void **arg) {
+ static void call(SlotRet (Obj::*f)(SlotArgs...) const noexcept, Obj *o, void **arg)
+ {
+ assertObjectType<Obj>(o);
(o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};