From 7b118c6456ba85a9f1c2fc0406d52829f1c8cdae Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 20 Apr 2012 14:45:21 +0200 Subject: Split qobject_impl.h into qobjectdefs_impl.h This is done to make QtPrivate::FunctionPointer available to the QMetaMethod declaration in qmetaobject.h (which already included qobjectdefs.h, since that's where QMetaObject is declared), so that the new template-based QMetaMethod::fromSignal() function may be implemented. The logic for statically generating the array of qMetaTypeId (used by the template-based QObject::connect()) remains in qobject_impl.h, since it's not needed for QMetaMethod::fromSignal(). Moreover, moving that code would introduce a circular dependency, since qmetatype.h as of commit 194674044693d6b101c3dc2f4784718540d343a4 now includes qobjectdefs.h. Change-Id: I36c35041e0c6661c3cf523684177a0b6c19e2d35 Reviewed-by: Olivier Goffart Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/kernel.pri | 1 + src/corelib/kernel/qobject_impl.h | 425 ----------------------------- src/corelib/kernel/qobjectdefs.h | 2 + src/corelib/kernel/qobjectdefs_impl.h | 485 ++++++++++++++++++++++++++++++++++ 4 files changed, 488 insertions(+), 425 deletions(-) create mode 100644 src/corelib/kernel/qobjectdefs_impl.h (limited to 'src') diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index bef2929214..b645d480d7 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -14,6 +14,7 @@ HEADERS += \ kernel/qobject.h \ kernel/qobject_impl.h \ kernel/qobjectdefs.h \ + kernel/qobjectdefs_impl.h \ kernel/qsignalmapper.h \ kernel/qsocketnotifier.h \ kernel/qtimer.h \ diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index 419fcc1dd4..e016002afa 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -51,431 +51,6 @@ QT_BEGIN_NAMESPACE namespace QtPrivate { - template struct RemoveRef { typedef T Type; }; - template struct RemoveRef { typedef T Type; }; - template struct RemoveConstRef { typedef T Type; }; - template struct RemoveConstRef { typedef T Type; }; - - /* - The following List classes are used to help to handle the list of arguments. - It follow the same principles as the lisp lists. - List_Left take a list and a number as a parametter and returns (via the Value typedef, - the list composed of the first N element of the list - */ -#ifndef Q_COMPILER_VARIADIC_TEMPLATES - template struct List { typedef Head Car; typedef Tail Cdr; }; - template struct List_Left { typedef List::Value > Value; }; - template struct List_Left { typedef void Value; }; -#else - // With variadic template, lists are represented using a variadic template argument instead of the lisp way - template struct List {}; - template struct List { typedef Head Car; typedef List Cdr; }; - template struct List_Append; - template struct List_Append, List> { typedef List Value; }; - template struct List_Left { - typedef typename List_Append,typename List_Left::Value>::Value Value; - }; - template struct List_Left { typedef List<> Value; }; -#endif - // List_Select returns (via typedef Value) the Nth element of the list L - template struct List_Select { typedef typename List_Select::Value Value; }; - template struct List_Select { typedef typename L::Car Value; }; - - /* - trick to set the return value of a slot that works even if the signal or the slot returns void - to be used like function(), ApplyReturnValue(&return_value) - if function() returns a value, the operator,(T, ApplyReturnValue) is called, but if it - returns void, the builtin one is used without an error. - */ - template - struct ApplyReturnValue { - void *data; - ApplyReturnValue(void *data_) : data(data_) {} - }; - template - void operator,(const T &value, const ApplyReturnValue &container) { - if (container.data) - *reinterpret_cast(container.data) = value; - } -#ifdef Q_COMPILER_RVALUE_REFS - template - void operator,(T &&value, const ApplyReturnValue &container) { - if (container.data) - *reinterpret_cast(container.data) = value; - } -#endif - template - void operator,(T, const ApplyReturnValue &) {} - - - /* - The FunctionPointer struct is a type trait for function pointer. - - ArgumentCount is the number of argument, or -1 if it is unknown - - the Object typedef is the Object of a pointer to member function - - the Arguments typedef is the list of argument (in a QtPrivate::List) - - the Function typedef is an alias to the template parametter Func - - the call(f,o,args) method is used to call that slot - Args is the list of argument of the signal - R is the return type of the signal - f is the function pointer - o is the receiver object - and args is the array of pointer to arguments, as used in qt_metacall - - The Functor struct is the helper to call a functor of N argument. - its call function is the same as the FunctionPointer::call function. - */ -#ifndef Q_COMPILER_VARIADIC_TEMPLATES - template struct FunctionPointer { enum {ArgumentCount = -1}; }; - template struct FunctionPointer - { - typedef Obj Object; - typedef void Arguments; - typedef Ret ReturnType; - typedef Ret (Obj::*Function) (); - enum {ArgumentCount = 0}; - template - static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue(arg[0]); } - }; - template struct FunctionPointer - { - typedef Obj Object; - typedef List Arguments; - typedef Ret ReturnType; - typedef Ret (Obj::*Function) (Arg1); - enum {ArgumentCount = 1}; - template - static void call(Function f, Obj *o, void **arg) { - (o->*f)((*reinterpret_cast::Type *>(arg[1]))), ApplyReturnValue(arg[0]); - } - }; - template struct FunctionPointer - { - typedef Obj Object; - typedef List > Arguments; - typedef Ret ReturnType; - typedef Ret (Obj::*Function) (Arg1, Arg2); - enum {ArgumentCount = 2}; - template - static void call(Function f, Obj *o, void **arg) { - (o->*f)( *reinterpret_cast::Value>::Type *>(arg[1]), - *reinterpret_cast::Value>::Type *>(arg[2])), ApplyReturnValue(arg[0]); - } - }; - template struct FunctionPointer - { - typedef Obj Object; - typedef List > > Arguments; - typedef Ret ReturnType; - typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3); - enum {ArgumentCount = 3}; - 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])), 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 - { - typedef void Arguments; - typedef Ret (*Function) (); - typedef Ret ReturnType; - enum {ArgumentCount = 0}; - template - static void call(Function f, void *, void **arg) { f(), ApplyReturnValue(arg[0]); } - }; - template struct FunctionPointer - { - typedef List Arguments; - typedef Ret ReturnType; - typedef Ret (*Function) (Arg1); - enum {ArgumentCount = 1}; - template - static void call(Function f, void *, void **arg) - { f(*reinterpret_cast::Value>::Type *>(arg[1])), ApplyReturnValue(arg[0]); } - }; - template struct FunctionPointer - { - typedef List > Arguments; - typedef Ret ReturnType; - typedef Ret (*Function) (Arg1, Arg2); - enum {ArgumentCount = 2}; - template - static void call(Function f, void *, void **arg) { - f(*reinterpret_cast::Value>::Type *>(arg[1]), - *reinterpret_cast::Value>::Type *>(arg[2])), ApplyReturnValue(arg[0]); } - }; - template struct FunctionPointer - { - typedef List > > Arguments; - typedef Ret ReturnType; - typedef Ret (*Function) (Arg1, Arg2, Arg3); - enum {ArgumentCount = 3}; - 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])), 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 - { - template - static void call(Function &f, void *, void **arg) { f(), ApplyReturnValue(arg[0]); } - }; - template struct Functor - { - template - static void call(Function &f, void *, void **arg) { - f(*reinterpret_cast::Value>::Type *>(arg[1])), 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])), 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[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; - template struct IndexesAppend, Right> - { typedef IndexesList Value; }; - template struct Indexes - { typedef typename IndexesAppend::Value, N - 1>::Value Value; }; - template <> struct Indexes<0> { typedef IndexesList<> Value; }; - template struct FunctionPointer { enum {ArgumentCount = -1}; }; - - template struct FunctorCall; - template - struct FunctorCall, List, R, Function> { - static void call(Function f, void **arg) { - f((*reinterpret_cast::Type *>(arg[I+1]))...), ApplyReturnValue(arg[0]); - } - }; - template - struct FunctorCall, List, R, SlotRet (Obj::*)(SlotArgs...)> { - static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) { - (o->*f)((*reinterpret_cast::Type *>(arg[I+1]))...), ApplyReturnValue(arg[0]); - } - }; - - template struct FunctionPointer - { - typedef Obj Object; - typedef List Arguments; - typedef Ret ReturnType; - typedef Ret (Obj::*Function) (Args...); - enum {ArgumentCount = sizeof...(Args)}; - template - static void call(Function f, Obj *o, void **arg) { - FunctorCall::Value, SignalArgs, R, Function>::call(f, o, arg); - } - }; - - template struct FunctionPointer - { - typedef List Arguments; - typedef Ret ReturnType; - typedef Ret (*Function) (Args...); - enum {ArgumentCount = sizeof...(Args)}; - template - static void call(Function f, void *, void **arg) { - FunctorCall::Value, SignalArgs, R, Function>::call(f, arg); - } - }; - - template struct Functor - { - template - static void call(Function &f, void *, void **arg) { - FunctorCall::Value, SignalArgs, R, Function>::call(f, arg); - } - }; -#endif - - /* - Logic that check if the arguments of the slot matches the argument of the signal. - To be used like this: - Q_STATIC_ASSERT(CheckCompatibleArguments::Arguments, FunctionPointer::Arguments>::value) - */ - template struct AreArgumentsCompatible { - static int test(A2); - static char test(...); - static A1 dummy(); - enum { value = sizeof(test(dummy())) == sizeof(int) }; - }; - template struct AreArgumentsCompatible { enum { value = false }; }; - template struct AreArgumentsCompatible { enum { value = true }; }; - // void as a return value - template struct AreArgumentsCompatible { enum { value = true }; }; - template struct AreArgumentsCompatible { enum { value = true }; }; - template<> struct AreArgumentsCompatible { enum { value = true }; }; - -#ifndef Q_COMPILER_VARIADIC_TEMPLATES - template struct CheckCompatibleArguments { enum { value = false }; }; - template <> struct CheckCompatibleArguments { enum { value = true }; }; - template struct CheckCompatibleArguments { enum { value = true }; }; - template struct CheckCompatibleArguments, List > - { - enum { value = AreArgumentsCompatible::Type, typename RemoveConstRef::Type>::value - && CheckCompatibleArguments::value }; - }; -#else - template struct CheckCompatibleArguments { enum { value = false }; }; - template <> struct CheckCompatibleArguments, List<>> { enum { value = true }; }; - template struct CheckCompatibleArguments> { enum { value = true }; }; - template - struct CheckCompatibleArguments, List> - { - enum { value = AreArgumentsCompatible::Type, typename RemoveConstRef::Type>::value - && CheckCompatibleArguments, List>::value }; - }; - -#endif - /* Logic to statically generate the array of qMetaTypeId ConnectionTypes::Arguments>::types() returns an array diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 9bcb8b9211..a52961bab7 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -44,6 +44,8 @@ #include +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h new file mode 100644 index 0000000000..5efe08b3e5 --- /dev/null +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -0,0 +1,485 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q_QDOC + +#ifndef QOBJECTDEFS_H +#error Do not include qobjectdefs_impl.h directly +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +namespace QtPrivate { + template struct RemoveRef { typedef T Type; }; + template struct RemoveRef { typedef T Type; }; + template struct RemoveConstRef { typedef T Type; }; + template struct RemoveConstRef { typedef T Type; }; + + /* + The following List classes are used to help to handle the list of arguments. + It follow the same principles as the lisp lists. + List_Left take a list and a number as a parametter and returns (via the Value typedef, + the list composed of the first N element of the list + */ +#ifndef Q_COMPILER_VARIADIC_TEMPLATES + template struct List { typedef Head Car; typedef Tail Cdr; }; + template struct List_Left { typedef List::Value > Value; }; + template struct List_Left { typedef void Value; }; +#else + // With variadic template, lists are represented using a variadic template argument instead of the lisp way + template struct List {}; + template struct List { typedef Head Car; typedef List Cdr; }; + template struct List_Append; + template struct List_Append, List> { typedef List Value; }; + template struct List_Left { + typedef typename List_Append,typename List_Left::Value>::Value Value; + }; + template struct List_Left { typedef List<> Value; }; +#endif + // List_Select returns (via typedef Value) the Nth element of the list L + template struct List_Select { typedef typename List_Select::Value Value; }; + template struct List_Select { typedef typename L::Car Value; }; + + /* + trick to set the return value of a slot that works even if the signal or the slot returns void + to be used like function(), ApplyReturnValue(&return_value) + if function() returns a value, the operator,(T, ApplyReturnValue) is called, but if it + returns void, the builtin one is used without an error. + */ + template + struct ApplyReturnValue { + void *data; + ApplyReturnValue(void *data_) : data(data_) {} + }; + template + void operator,(const T &value, const ApplyReturnValue &container) { + if (container.data) + *reinterpret_cast(container.data) = value; + } +#ifdef Q_COMPILER_RVALUE_REFS + template + void operator,(T &&value, const ApplyReturnValue &container) { + if (container.data) + *reinterpret_cast(container.data) = value; + } +#endif + template + void operator,(T, const ApplyReturnValue &) {} + + + /* + The FunctionPointer struct is a type trait for function pointer. + - ArgumentCount is the number of argument, or -1 if it is unknown + - the Object typedef is the Object of a pointer to member function + - the Arguments typedef is the list of argument (in a QtPrivate::List) + - the Function typedef is an alias to the template parametter Func + - the call(f,o,args) method is used to call that slot + Args is the list of argument of the signal + R is the return type of the signal + f is the function pointer + o is the receiver object + and args is the array of pointer to arguments, as used in qt_metacall + + The Functor struct is the helper to call a functor of N argument. + its call function is the same as the FunctionPointer::call function. + */ +#ifndef Q_COMPILER_VARIADIC_TEMPLATES + template struct FunctionPointer { enum {ArgumentCount = -1}; }; + template struct FunctionPointer + { + typedef Obj Object; + typedef void Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (); + enum {ArgumentCount = 0}; + template + static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue(arg[0]); } + }; + template struct FunctionPointer + { + typedef Obj Object; + typedef List Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Arg1); + enum {ArgumentCount = 1}; + template + static void call(Function f, Obj *o, void **arg) { + (o->*f)((*reinterpret_cast::Type *>(arg[1]))), ApplyReturnValue(arg[0]); + } + }; + template struct FunctionPointer + { + typedef Obj Object; + typedef List > Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Arg1, Arg2); + enum {ArgumentCount = 2}; + template + static void call(Function f, Obj *o, void **arg) { + (o->*f)( *reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2])), ApplyReturnValue(arg[0]); + } + }; + template struct FunctionPointer + { + typedef Obj Object; + typedef List > > Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3); + enum {ArgumentCount = 3}; + 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])), 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 + { + typedef void Arguments; + typedef Ret (*Function) (); + typedef Ret ReturnType; + enum {ArgumentCount = 0}; + template + static void call(Function f, void *, void **arg) { f(), ApplyReturnValue(arg[0]); } + }; + template struct FunctionPointer + { + typedef List Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Arg1); + enum {ArgumentCount = 1}; + template + static void call(Function f, void *, void **arg) + { f(*reinterpret_cast::Value>::Type *>(arg[1])), ApplyReturnValue(arg[0]); } + }; + template struct FunctionPointer + { + typedef List > Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Arg1, Arg2); + enum {ArgumentCount = 2}; + template + static void call(Function f, void *, void **arg) { + f(*reinterpret_cast::Value>::Type *>(arg[1]), + *reinterpret_cast::Value>::Type *>(arg[2])), ApplyReturnValue(arg[0]); } + }; + template struct FunctionPointer + { + typedef List > > Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Arg1, Arg2, Arg3); + enum {ArgumentCount = 3}; + 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])), 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 + { + template + static void call(Function &f, void *, void **arg) { f(), ApplyReturnValue(arg[0]); } + }; + template struct Functor + { + template + static void call(Function &f, void *, void **arg) { + f(*reinterpret_cast::Value>::Type *>(arg[1])), 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])), 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[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; + template struct IndexesAppend, Right> + { typedef IndexesList Value; }; + template struct Indexes + { typedef typename IndexesAppend::Value, N - 1>::Value Value; }; + template <> struct Indexes<0> { typedef IndexesList<> Value; }; + template struct FunctionPointer { enum {ArgumentCount = -1}; }; + + template struct FunctorCall; + template + struct FunctorCall, List, R, Function> { + static void call(Function f, void **arg) { + f((*reinterpret_cast::Type *>(arg[I+1]))...), ApplyReturnValue(arg[0]); + } + }; + template + struct FunctorCall, List, R, SlotRet (Obj::*)(SlotArgs...)> { + static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) { + (o->*f)((*reinterpret_cast::Type *>(arg[I+1]))...), ApplyReturnValue(arg[0]); + } + }; + + template struct FunctionPointer + { + typedef Obj Object; + typedef List Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Args...); + enum {ArgumentCount = sizeof...(Args)}; + template + static void call(Function f, Obj *o, void **arg) { + FunctorCall::Value, SignalArgs, R, Function>::call(f, o, arg); + } + }; + + template struct FunctionPointer + { + typedef List Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Args...); + enum {ArgumentCount = sizeof...(Args)}; + template + static void call(Function f, void *, void **arg) { + FunctorCall::Value, SignalArgs, R, Function>::call(f, arg); + } + }; + + template struct Functor + { + template + static void call(Function &f, void *, void **arg) { + FunctorCall::Value, SignalArgs, R, Function>::call(f, arg); + } + }; +#endif + + /* + Logic that check if the arguments of the slot matches the argument of the signal. + To be used like this: + Q_STATIC_ASSERT(CheckCompatibleArguments::Arguments, FunctionPointer::Arguments>::value) + */ + template struct AreArgumentsCompatible { + static int test(A2); + static char test(...); + static A1 dummy(); + enum { value = sizeof(test(dummy())) == sizeof(int) }; + }; + template struct AreArgumentsCompatible { enum { value = false }; }; + template struct AreArgumentsCompatible { enum { value = true }; }; + // void as a return value + template struct AreArgumentsCompatible { enum { value = true }; }; + template struct AreArgumentsCompatible { enum { value = true }; }; + template<> struct AreArgumentsCompatible { enum { value = true }; }; + +#ifndef Q_COMPILER_VARIADIC_TEMPLATES + template struct CheckCompatibleArguments { enum { value = false }; }; + template <> struct CheckCompatibleArguments { enum { value = true }; }; + template struct CheckCompatibleArguments { enum { value = true }; }; + template struct CheckCompatibleArguments, List > + { + enum { value = AreArgumentsCompatible::Type, typename RemoveConstRef::Type>::value + && CheckCompatibleArguments::value }; + }; +#else + template struct CheckCompatibleArguments { enum { value = false }; }; + template <> struct CheckCompatibleArguments, List<>> { enum { value = true }; }; + template struct CheckCompatibleArguments> { enum { value = true }; }; + template + struct CheckCompatibleArguments, List> + { + enum { value = AreArgumentsCompatible::Type, typename RemoveConstRef::Type>::value + && CheckCompatibleArguments, List>::value }; + }; + +#endif +} + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif -- cgit v1.2.3