From cc9c85ecd68c8dae28567dac630f894faaaf1acf Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 8 Nov 2011 18:34:47 +0100 Subject: [PATCH] Support for up to 6 arguments in the new connection syntax For compilations without variadic template support Change-Id: I78af4f6022ad7a0923e5c5788a34eb7d834f50f3 Reviewed-by: Bradley T. Hughes --- doc/src/core/objectmodel/signalsandslots.qdoc | 2 +- src/corelib/kernel/qobject_impl.h | 139 ++++++++++++++++++ .../corelib/kernel/qobject/tst_qobject.cpp | 2 - 3 files changed, 140 insertions(+), 3 deletions(-) diff --git a/doc/src/core/objectmodel/signalsandslots.qdoc b/doc/src/core/objectmodel/signalsandslots.qdoc index 175f7e1b07..821147fcfd 100644 --- a/doc/src/core/objectmodel/signalsandslots.qdoc +++ b/doc/src/core/objectmodel/signalsandslots.qdoc @@ -396,7 +396,7 @@ \endcode Note that if your compiler does not support C++11 variadic templates, - this syntax only works if the signal and slot have 3 arguments or less. + this syntax only works if the signal and slot have 6 arguments or less. The other way to connect a signal to a slot is to use QObject::connect() and the \c{SIGNAL} and \c{SLOT} macros. diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index d34b81ceaf..3c7dacf527 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -177,6 +177,55 @@ namespace QtPrivate { *reinterpret_cast::Value>::Type *>(arg[3])), ApplyReturnValue(arg[0]); } }; + template struct FunctionPointer + { + typedef Obj Object; + typedef List > > > Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4); + enum {ArgumentCount = 4}; + template + static void call(Function f, Obj *o, void **arg) { + (o->*f)( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4])), ApplyReturnValue(arg[0]); + } + }; + template struct FunctionPointer + { + typedef Obj Object; + typedef List > > > > Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5); + enum {ArgumentCount = 5}; + template + static void call(Function f, Obj *o, void **arg) { + (o->*f)( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4]), + *reinterpret_cast::Value>::Type *>(arg[5])), ApplyReturnValue(arg[0]); + } + }; + template + struct FunctionPointer + { + typedef Obj Object; + typedef List > > > > > Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); + enum {ArgumentCount = 6}; + template + static void call(Function f, Obj *o, void **arg) { + (o->*f)( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4]), + *reinterpret_cast::Value>::Type *>(arg[5]), + *reinterpret_cast::Value>::Type *>(arg[6])), ApplyReturnValue(arg[0]); + } + }; template struct FunctionPointer { @@ -221,6 +270,52 @@ namespace QtPrivate { *reinterpret_cast::Value>::Type *>(arg[3])), ApplyReturnValue(arg[0]); } }; + template struct FunctionPointer + { + typedef List > > > Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4); + enum {ArgumentCount = 4}; + template + static void call(Function f, void *, void **arg) { + f( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4])), ApplyReturnValue(arg[0]); + } + }; + template struct FunctionPointer + { + typedef List > > > > Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5); + enum {ArgumentCount = 5}; + template + static void call(Function f, void *, void **arg) { + f( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4]), + *reinterpret_cast::Value>::Type *>(arg[5])), ApplyReturnValue(arg[0]); + } + }; + template struct FunctionPointer + { + typedef List > > > > > Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); + enum {ArgumentCount = 6}; + template + static void call(Function f, void *, void **arg) { + f( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4]), + *reinterpret_cast::Value>::Type *>(arg[5]), + *reinterpret_cast::Value>::Type *>(arg[6])), ApplyReturnValue(arg[0]); + } + }; template struct Functor; template struct Functor @@ -252,6 +347,39 @@ namespace QtPrivate { *reinterpret_cast::Value>::Type *>(arg[4])), ApplyReturnValue(arg[0]); } }; + template struct Functor + { + template + static void call(Function &f, void *, void **arg) { + f( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4])), ApplyReturnValue(arg[0]); + } + }; + template struct Functor + { + template + static void call(Function &f, void *, void **arg) { + f( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4]), + *reinterpret_cast::Value>::Type *>(arg[5])), ApplyReturnValue(arg[0]); + } + }; + template struct Functor + { + template + static void call(Function &f, void *, void **arg) { + f( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2]), + *reinterpret_cast::Value>::Type *>(arg[3]), + *reinterpret_cast::Value>::Type *>(arg[4]), + *reinterpret_cast::Value>::Type *>(arg[5]), + *reinterpret_cast::Value>::Type *>(arg[6])), ApplyReturnValue(arg[0]); + } + }; #else template struct IndexesList {}; template struct IndexesAppend; @@ -372,6 +500,17 @@ namespace QtPrivate { template struct ConnectionTypes > >, true> { static const int *types() { static const int t[4] = { QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), 0 }; return t; } }; + template struct ConnectionTypes > > >, true> + { static const int *types() { static const int t[4] = { QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), + QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), 0 }; return t; } }; + template struct ConnectionTypes > > > >, true> + { static const int *types() { static const int t[4] = { QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), + QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), 0 }; return t; } }; + template + struct ConnectionTypes > > > > >, true> + { static const int *types() { static const int t[4] = { QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), + QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), + QtPrivate::QMetaTypeIdHelper::qt_metatype_id(), 0 }; return t; } }; #else template struct TypesAreDeclaredMetaType { enum { Value = false }; }; template <> struct TypesAreDeclaredMetaType> { enum { Value = true }; }; diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index f5a079fae5..1b5e3bd79e 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -4793,7 +4793,6 @@ namespace ManyArgumentNamespace { void tst_QObject::connectManyArguments() { -#ifdef Q_COMPILER_VARIADIC_TEMPLATES ManyArgumentObject ob; ob.count = 0; ManyArgumentNamespace::count = 0; @@ -4841,7 +4840,6 @@ void tst_QObject::connectManyArguments() emit ob2.signal6("a", "b", "c", "d", "e", "f"); QCOMPARE(ob2.count, 6); QCOMPARE(ManyArgumentNamespace::count, 6); -#endif } class ReturnValue : public QObject {