LCOV - code coverage report
Current view: top level - usr/include/x86_64-linux-gnu/qt5/QtCore - qobjectdefs_impl.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 7 13 53.8 %
Date: 2016-09-12 13:07:23 Functions: 15 25 60.0 %

          Line data    Source code
       1             : /****************************************************************************
       2             : **
       3             : ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
       4             : ** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
       5             : ** Contact: http://www.qt-project.org/legal
       6             : **
       7             : ** This file is part of the QtCore module of the Qt Toolkit.
       8             : **
       9             : ** $QT_BEGIN_LICENSE:LGPL$
      10             : ** Commercial License Usage
      11             : ** Licensees holding valid commercial Qt licenses may use this file in
      12             : ** accordance with the commercial license agreement provided with the
      13             : ** Software or, alternatively, in accordance with the terms contained in
      14             : ** a written agreement between you and Digia.  For licensing terms and
      15             : ** conditions see http://qt.digia.com/licensing.  For further information
      16             : ** use the contact form at http://qt.digia.com/contact-us.
      17             : **
      18             : ** GNU Lesser General Public License Usage
      19             : ** Alternatively, this file may be used under the terms of the GNU Lesser
      20             : ** General Public License version 2.1 as published by the Free Software
      21             : ** Foundation and appearing in the file LICENSE.LGPL included in the
      22             : ** packaging of this file.  Please review the following information to
      23             : ** ensure the GNU Lesser General Public License version 2.1 requirements
      24             : ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
      25             : **
      26             : ** In addition, as a special exception, Digia gives you certain additional
      27             : ** rights.  These rights are described in the Digia Qt LGPL Exception
      28             : ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
      29             : **
      30             : ** GNU General Public License Usage
      31             : ** Alternatively, this file may be used under the terms of the GNU
      32             : ** General Public License version 3.0 as published by the Free Software
      33             : ** Foundation and appearing in the file LICENSE.GPL included in the
      34             : ** packaging of this file.  Please review the following information to
      35             : ** ensure the GNU General Public License version 3.0 requirements will be
      36             : ** met: http://www.gnu.org/copyleft/gpl.html.
      37             : **
      38             : **
      39             : ** $QT_END_LICENSE$
      40             : **
      41             : ****************************************************************************/
      42             : 
      43             : #ifndef Q_QDOC
      44             : 
      45             : #ifndef QOBJECTDEFS_H
      46             : #error Do not include qobjectdefs_impl.h directly
      47             : #endif
      48             : 
      49             : #if 0
      50             : #pragma qt_sync_skip_header_check
      51             : #pragma qt_sync_stop_processing
      52             : #endif
      53             : 
      54             : QT_BEGIN_NAMESPACE
      55             : 
      56             : 
      57             : namespace QtPrivate {
      58             :     template <typename T> struct RemoveRef { typedef T Type; };
      59             :     template <typename T> struct RemoveRef<T&> { typedef T Type; };
      60             :     template <typename T> struct RemoveConstRef { typedef T Type; };
      61             :     template <typename T> struct RemoveConstRef<const T&> { typedef T Type; };
      62             : 
      63             :     /*
      64             :        The following List classes are used to help to handle the list of arguments.
      65             :        It follow the same principles as the lisp lists.
      66             :        List_Left<L,N> take a list and a number as a parameter and returns (via the Value typedef,
      67             :        the list composed of the first N element of the list
      68             :      */
      69             : #ifndef Q_COMPILER_VARIADIC_TEMPLATES
      70             :     template <typename Head, typename Tail> struct List { typedef Head Car; typedef Tail Cdr; };
      71             :     template <typename L, int N> struct List_Left { typedef List<typename L::Car, typename List_Left<typename L::Cdr, N - 1>::Value > Value; };
      72             :     template <typename L> struct List_Left<L,0> { typedef void Value; };
      73             : #else
      74             :     // With variadic template, lists are represented using a variadic template argument instead of the lisp way
      75             :     template <typename...> struct List {};
      76             :     template <typename Head, typename... Tail> struct List<Head, Tail...> { typedef Head Car; typedef List<Tail...> Cdr; };
      77             :     template <typename, typename> struct List_Append;
      78             :     template <typename... L1, typename...L2> struct List_Append<List<L1...>, List<L2...>> { typedef List<L1..., L2...> Value; };
      79             :     template <typename L, int N> struct List_Left {
      80             :         typedef typename List_Append<List<typename L::Car>,typename List_Left<typename L::Cdr, N - 1>::Value>::Value Value;
      81             :     };
      82             :     template <typename L> struct List_Left<L, 0> { typedef List<> Value; };
      83             : #endif
      84             :     // List_Select<L,N> returns (via typedef Value) the Nth element of the list L
      85             :     template <typename L, int N> struct List_Select { typedef typename List_Select<typename L::Cdr, N - 1>::Value Value; };
      86             :     template <typename L> struct List_Select<L,0> { typedef typename L::Car Value; };
      87             : 
      88             :     /*
      89             :        trick to set the return value of a slot that works even if the signal or the slot returns void
      90             :        to be used like     function(), ApplyReturnValue<ReturnType>(&return_value)
      91             :        if function() returns a value, the operator,(T, ApplyReturnValue<ReturnType>) is called, but if it
      92             :        returns void, the builtin one is used without an error.
      93             :     */
      94             :     template <typename T>
      95             :     struct ApplyReturnValue {
      96             :         void *data;
      97           8 :         explicit ApplyReturnValue(void *data_) : data(data_) {}
      98             :     };
      99             :     template<typename T, typename U>
     100             :     void operator,(const T &value, const ApplyReturnValue<U> &container) {
     101             :         if (container.data)
     102             :             *reinterpret_cast<U*>(container.data) = value;
     103             :     }
     104             : #ifdef Q_COMPILER_RVALUE_REFS
     105             :     template<typename T, typename U>
     106             :     void operator,(T &&value, const ApplyReturnValue<U> &container) {
     107             :         if (container.data)
     108             :             *reinterpret_cast<U*>(container.data) = value;
     109             :     }
     110             : #endif
     111             :     template<typename T>
     112             :     void operator,(T, const ApplyReturnValue<void> &) {}
     113             : 
     114             : 
     115             :     /*
     116             :       The FunctionPointer<Func> struct is a type trait for function pointer.
     117             :         - ArgumentCount  is the number of argument, or -1 if it is unknown
     118             :         - the Object typedef is the Object of a pointer to member function
     119             :         - the Arguments typedef is the list of argument (in a QtPrivate::List)
     120             :         - the Function typedef is an alias to the template parameter Func
     121             :         - the call<Args, R>(f,o,args) method is used to call that slot
     122             :             Args is the list of argument of the signal
     123             :             R is the return type of the signal
     124             :             f is the function pointer
     125             :             o is the receiver object
     126             :             and args is the array of pointer to arguments, as used in qt_metacall
     127             : 
     128             :        The Functor<Func,N> struct is the helper to call a functor of N argument.
     129             :        its call function is the same as the FunctionPointer::call function.
     130             :      */
     131             : #ifndef Q_COMPILER_VARIADIC_TEMPLATES
     132             :     template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
     133             :     //Pointers to member functions
     134             :     template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) ()>
     135             :     {
     136             :         typedef Obj Object;
     137             :         typedef void Arguments;
     138             :         typedef Ret ReturnType;
     139             :         typedef Ret (Obj::*Function) ();
     140             :         enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
     141             :         template <typename Args, typename R>
     142             :         static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
     143             :     };
     144             :     template<class Obj, typename Ret, typename Arg1> struct FunctionPointer<Ret (Obj::*) (Arg1)>
     145             :     {
     146             :         typedef Obj Object;
     147             :         typedef List<Arg1, void> Arguments;
     148             :         typedef Ret ReturnType;
     149             :         typedef Ret (Obj::*Function) (Arg1);
     150             :         enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
     151             :         template <typename Args, typename R>
     152             :         static void call(Function f, Obj *o, void **arg) {
     153             :             (o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
     154             :         }
     155             :     };
     156             :     template<class Obj, typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2)>
     157             :     {
     158             :         typedef Obj Object;
     159             :         typedef List<Arg1, List<Arg2, void> >  Arguments;
     160             :         typedef Ret ReturnType;
     161             :         typedef Ret (Obj::*Function) (Arg1, Arg2);
     162             :         enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
     163             :         template <typename Args, typename R>
     164             :         static void call(Function f, Obj *o, void **arg) {
     165             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     166             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
     167             :         }
     168             :     };
     169             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3)>
     170             :     {
     171             :         typedef Obj Object;
     172             :         typedef List<Arg1, List<Arg2, List<Arg3, void> > >  Arguments;
     173             :         typedef Ret ReturnType;
     174             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3);
     175             :         enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
     176             :         template <typename Args, typename R>
     177             :         static void call(Function f, Obj *o, void **arg) {
     178             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     179             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     180             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
     181             :         }
     182             :     };
     183             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4)>
     184             :     {
     185             :         typedef Obj Object;
     186             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > >  Arguments;
     187             :         typedef Ret ReturnType;
     188             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4);
     189             :         enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
     190             :         template <typename Args, typename R>
     191             :         static void call(Function f, Obj *o, void **arg) {
     192             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     193             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     194             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     195             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
     196             :         }
     197             :     };
     198             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
     199             :     {
     200             :         typedef Obj Object;
     201             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > >  Arguments;
     202             :         typedef Ret ReturnType;
     203             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
     204             :         enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
     205             :         template <typename Args, typename R>
     206             :         static void call(Function f, Obj *o, void **arg) {
     207             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     208             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     209             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     210             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     211             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
     212             :         }
     213             :     };
     214             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
     215             :     struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
     216             :     {
     217             :         typedef Obj Object;
     218             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > >  Arguments;
     219             :         typedef Ret ReturnType;
     220             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
     221             :         enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
     222             :         template <typename Args, typename R>
     223             :         static void call(Function f, Obj *o, void **arg) {
     224             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     225             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     226             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     227             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     228             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
     229             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
     230             :         }
     231             :     };
     232             : 
     233             :     //Pointers to const member functions
     234             :     template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) () const>
     235             :     {
     236             :         typedef Obj Object;
     237             :         typedef void Arguments;
     238             :         typedef Ret ReturnType;
     239             :         typedef Ret (Obj::*Function) () const;
     240             :         enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
     241             :         template <typename Args, typename R>
     242             :         static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
     243             :     };
     244             :     template<class Obj, typename Ret, typename Arg1> struct FunctionPointer<Ret (Obj::*) (Arg1) const>
     245             :     {
     246             :         typedef Obj Object;
     247             :         typedef List<Arg1, void> Arguments;
     248             :         typedef Ret ReturnType;
     249             :         typedef Ret (Obj::*Function) (Arg1) const;
     250             :         enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
     251             :         template <typename Args, typename R>
     252             :         static void call(Function f, Obj *o, void **arg) {
     253             :             (o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
     254             :         }
     255             :     };
     256             :     template<class Obj, typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2) const>
     257             :     {
     258             :         typedef Obj Object;
     259             :         typedef List<Arg1, List<Arg2, void> >  Arguments;
     260             :         typedef Ret ReturnType;
     261             :         typedef Ret (Obj::*Function) (Arg1, Arg2) const;
     262             :         enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
     263             :         template <typename Args, typename R>
     264             :         static void call(Function f, Obj *o, void **arg) {
     265             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     266             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
     267             :         }
     268             :     };
     269             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3) const>
     270             :     {
     271             :         typedef Obj Object;
     272             :         typedef List<Arg1, List<Arg2, List<Arg3, void> > >  Arguments;
     273             :         typedef Ret ReturnType;
     274             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3) const;
     275             :         enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
     276             :         template <typename Args, typename R>
     277             :         static void call(Function f, Obj *o, void **arg) {
     278             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     279             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     280             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
     281             :         }
     282             :     };
     283             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4) const>
     284             :     {
     285             :         typedef Obj Object;
     286             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > >  Arguments;
     287             :         typedef Ret ReturnType;
     288             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4) const;
     289             :         enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
     290             :         template <typename Args, typename R>
     291             :         static void call(Function f, Obj *o, void **arg) {
     292             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     293             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     294             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     295             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
     296             :         }
     297             :     };
     298             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5) const>
     299             :     {
     300             :         typedef Obj Object;
     301             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > >  Arguments;
     302             :         typedef Ret ReturnType;
     303             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5) const;
     304             :         enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
     305             :         template <typename Args, typename R>
     306             :         static void call(Function f, Obj *o, void **arg) {
     307             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     308             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     309             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     310             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     311             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
     312             :         }
     313             :     };
     314             :     template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
     315             :     struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const>
     316             :     {
     317             :         typedef Obj Object;
     318             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > >  Arguments;
     319             :         typedef Ret ReturnType;
     320             :         typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const;
     321             :         enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
     322             :         template <typename Args, typename R>
     323             :         static void call(Function f, Obj *o, void **arg) {
     324             :             (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     325             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     326             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     327             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     328             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
     329             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
     330             :         }
     331             :     };
     332             : 
     333             :     //Static functions
     334             :     template<typename Ret> struct FunctionPointer<Ret (*) ()>
     335             :     {
     336             :         typedef void Arguments;
     337             :         typedef Ret (*Function) ();
     338             :         typedef Ret ReturnType;
     339             :         enum {ArgumentCount = 0, IsPointerToMemberFunction = false};
     340             :         template <typename Args, typename R>
     341             :         static void call(Function f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
     342             :     };
     343             :     template<typename Ret, typename Arg1> struct FunctionPointer<Ret (*) (Arg1)>
     344             :     {
     345             :         typedef List<Arg1, void> Arguments;
     346             :         typedef Ret ReturnType;
     347             :         typedef Ret (*Function) (Arg1);
     348             :         enum {ArgumentCount = 1, IsPointerToMemberFunction = false};
     349             :         template <typename Args, typename R>
     350             :         static void call(Function f, void *, void **arg)
     351             :         { f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]); }
     352             :     };
     353             :     template<typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (*) (Arg1, Arg2)>
     354             :     {
     355             :         typedef List<Arg1, List<Arg2, void> > Arguments;
     356             :         typedef Ret ReturnType;
     357             :         typedef Ret (*Function) (Arg1, Arg2);
     358             :         enum {ArgumentCount = 2, IsPointerToMemberFunction = false};
     359             :         template <typename Args, typename R>
     360             :         static void call(Function f, void *, void **arg) {
     361             :             f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     362             :               *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]); }
     363             :     };
     364             :     template<typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3)>
     365             :     {
     366             :         typedef List<Arg1, List<Arg2, List<Arg3, void> > >  Arguments;
     367             :         typedef Ret ReturnType;
     368             :         typedef Ret (*Function) (Arg1, Arg2, Arg3);
     369             :         enum {ArgumentCount = 3, IsPointerToMemberFunction = false};
     370             :         template <typename Args, typename R>
     371             :         static void call(Function f, void *, void **arg) {
     372             :             f(       *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     373             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     374             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
     375             :         }
     376             :     };
     377             :     template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4)>
     378             :     {
     379             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > >  Arguments;
     380             :         typedef Ret ReturnType;
     381             :         typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4);
     382             :         enum {ArgumentCount = 4, IsPointerToMemberFunction = false};
     383             :         template <typename Args, typename R>
     384             :         static void call(Function f, void *, void **arg) {
     385             :             f(       *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     386             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     387             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     388             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
     389             :         }
     390             :     };
     391             :     template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
     392             :     {
     393             :         typedef List<Arg1, List<Arg2, List<Arg3,
     394             :         List<Arg4, List<Arg5, void > > > > >  Arguments;
     395             :         typedef Ret ReturnType;
     396             :         typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
     397             :         enum {ArgumentCount = 5, IsPointerToMemberFunction = false};
     398             :         template <typename Args, typename R>
     399             :         static void call(Function f, void *, void **arg) {
     400             :             f(       *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     401             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     402             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     403             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     404             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
     405             :         }
     406             :     };
     407             :     template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
     408             :     {
     409             :         typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > >  Arguments;
     410             :         typedef Ret ReturnType;
     411             :         typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
     412             :         enum {ArgumentCount = 6, IsPointerToMemberFunction = false};
     413             :         template <typename Args, typename R>
     414             :         static void call(Function f, void *, void **arg) {
     415             :             f(       *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     416             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     417             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     418             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     419             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
     420             :                      *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
     421             :         }
     422             :     };
     423             : 
     424             :     //Functors
     425             :     template<typename F, int N> struct Functor;
     426             :     template<typename Function> struct Functor<Function, 0>
     427             :     {
     428             :         template <typename Args, typename R>
     429             :         static void call(Function &f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
     430             :     };
     431             :     template<typename Function> struct Functor<Function, 1>
     432             :     {
     433             :         template <typename Args, typename R>
     434             :         static void call(Function &f, void *, void **arg) {
     435             :             f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]);
     436             :         }
     437             :     };
     438             :     template<typename Function> struct Functor<Function, 2>
     439             :     {
     440             :         template <typename Args, typename R>
     441             :         static void call(Function &f, void *, void **arg) {
     442             :             f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     443             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
     444             :         }
     445             :     };
     446             :     template<typename Function> struct Functor<Function, 3>
     447             :     {
     448             :         template <typename Args, typename R>
     449             :         static void call(Function &f, void *, void **arg) {
     450             :             f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     451             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     452             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
     453             :         }
     454             :     };
     455             :     template<typename Function> struct Functor<Function, 4>
     456             :     {
     457             :         template <typename Args, typename R>
     458             :         static void call(Function &f, void *, void **arg) {
     459             :             f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     460             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     461             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     462             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
     463             :         }
     464             :     };
     465             :     template<typename Function> struct Functor<Function, 5>
     466             :     {
     467             :         template <typename Args, typename R>
     468             :         static void call(Function &f, void *, void **arg) {
     469             :             f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     470             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     471             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     472             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     473             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
     474             :         }
     475             :     };
     476             :     template<typename Function> struct Functor<Function, 6>
     477             :     {
     478             :         template <typename Args, typename R>
     479             :         static void call(Function &f, void *, void **arg) {
     480             :             f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
     481             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
     482             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
     483             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
     484             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
     485             :                *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
     486             :         }
     487             :     };
     488             : #else
     489             :     template <int...> struct IndexesList {};
     490             :     template <typename IndexList, int Right> struct IndexesAppend;
     491             :     template <int... Left, int Right> struct IndexesAppend<IndexesList<Left...>, Right>
     492             :     { typedef IndexesList<Left..., Right> Value; };
     493             :     template <int N> struct Indexes
     494             :     { typedef typename IndexesAppend<typename Indexes<N - 1>::Value, N - 1>::Value Value; };
     495             :     template <> struct Indexes<0> { typedef IndexesList<> Value; };
     496             :     template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
     497             : 
     498             :     template <typename, typename, typename, typename> struct FunctorCall;
     499             :     template <int... II, typename... SignalArgs, typename R, typename Function>
     500             :     struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, Function> {
     501           8 :         static void call(Function f, void **arg) {
     502           8 :             f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
     503           8 :         }
     504             :     };
     505             :     template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
     506             :     struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
     507           0 :         static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) {
     508           0 :             (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
     509           0 :         }
     510             :     };
     511             :     template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
     512             :     struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const> {
     513             :         static void call(SlotRet (Obj::*f)(SlotArgs...) const, Obj *o, void **arg) {
     514             :             (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
     515             :         }
     516             :     };
     517             : 
     518             :     template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...)>
     519             :     {
     520             :         typedef Obj Object;
     521             :         typedef List<Args...>  Arguments;
     522             :         typedef Ret ReturnType;
     523             :         typedef Ret (Obj::*Function) (Args...);
     524             :         enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
     525             :         template <typename SignalArgs, typename R>
     526           0 :         static void call(Function f, Obj *o, void **arg) {
     527           0 :             FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
     528           0 :         }
     529             :     };
     530             :     template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...) const>
     531             :     {
     532             :         typedef Obj Object;
     533             :         typedef List<Args...>  Arguments;
     534             :         typedef Ret ReturnType;
     535             :         typedef Ret (Obj::*Function) (Args...) const;
     536             :         enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
     537             :         template <typename SignalArgs, typename R>
     538             :         static void call(Function f, Obj *o, void **arg) {
     539             :             FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
     540             :         }
     541             :     };
     542             : 
     543             :     template<typename Ret, typename... Args> struct FunctionPointer<Ret (*) (Args...)>
     544             :     {
     545             :         typedef List<Args...> Arguments;
     546             :         typedef Ret ReturnType;
     547             :         typedef Ret (*Function) (Args...);
     548             :         enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = false};
     549             :         template <typename SignalArgs, typename R>
     550             :         static void call(Function f, void *, void **arg) {
     551             :             FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, arg);
     552             :         }
     553             :     };
     554             : 
     555             :     template<typename Function, int N> struct Functor
     556             :     {
     557             :         template <typename SignalArgs, typename R>
     558           8 :         static void call(Function &f, void *, void **arg) {
     559           8 :             FunctorCall<typename Indexes<N>::Value, SignalArgs, R, Function>::call(f, arg);
     560           8 :         }
     561             :     };
     562             : #endif
     563             : 
     564             :     /*
     565             :        Logic that check if the arguments of the slot matches the argument of the signal.
     566             :        To be used like this:
     567             :        Q_STATIC_ASSERT(CheckCompatibleArguments<FunctionPointer<Signal>::Arguments, FunctionPointer<Slot>::Arguments>::value)
     568             :     */
     569             :     template<typename A1, typename A2> struct AreArgumentsCompatible {
     570             :         static int test(const typename RemoveRef<A2>::Type&);
     571             :         static char test(...);
     572             :         static const typename RemoveRef<A1>::Type &dummy();
     573             :         enum { value = sizeof(test(dummy())) == sizeof(int) };
     574             :     };
     575             :     template<typename A1, typename A2> struct AreArgumentsCompatible<A1, A2&> { enum { value = false }; };
     576             :     template<typename A> struct AreArgumentsCompatible<A&, A&> { enum { value = true }; };
     577             :     // void as a return value
     578             :     template<typename A> struct AreArgumentsCompatible<void, A> { enum { value = true }; };
     579             :     template<typename A> struct AreArgumentsCompatible<A, void> { enum { value = true }; };
     580             :     template<> struct AreArgumentsCompatible<void, void> { enum { value = true }; };
     581             : 
     582             : #ifndef Q_COMPILER_VARIADIC_TEMPLATES
     583             :     template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
     584             :     template <> struct CheckCompatibleArguments<void, void> { enum { value = true }; };
     585             :     template <typename List1> struct CheckCompatibleArguments<List1, void> { enum { value = true }; };
     586             :     template <typename Arg1, typename Arg2, typename Tail1, typename Tail2> struct CheckCompatibleArguments<List<Arg1, Tail1>, List<Arg2, Tail2> >
     587             :     {
     588             :         enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
     589             :                     && CheckCompatibleArguments<Tail1, Tail2>::value };
     590             :     };
     591             : #else
     592             :     template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
     593             :     template <> struct CheckCompatibleArguments<List<>, List<>> { enum { value = true }; };
     594             :     template <typename List1> struct CheckCompatibleArguments<List1, List<>> { enum { value = true }; };
     595             :     template <typename Arg1, typename Arg2, typename... Tail1, typename... Tail2>
     596             :     struct CheckCompatibleArguments<List<Arg1, Tail1...>, List<Arg2, Tail2...>>
     597             :     {
     598             :         enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
     599             :                     && CheckCompatibleArguments<List<Tail1...>, List<Tail2...>>::value };
     600             :     };
     601             : #endif
     602             : 
     603             : #if defined(Q_COMPILER_DECLTYPE) && defined(Q_COMPILER_VARIADIC_TEMPLATES)
     604             :     /*
     605             :        Find the maximum number of arguments a functor object can take and be still compatible with
     606             :        the arguments from the signal.
     607             :        Value is the number of arguments, or -1 if nothing matches.
     608             :      */
     609             :     template <typename Functor, typename ArgList> struct ComputeFunctorArgumentCount;
     610             : 
     611             :     template <typename Functor, typename ArgList, bool Done> struct ComputeFunctorArgumentCountHelper
     612             :     { enum { Value = -1 }; };
     613             :     template <typename Functor, typename First, typename... ArgList>
     614             :     struct ComputeFunctorArgumentCountHelper<Functor, List<First, ArgList...>, false>
     615             :         : ComputeFunctorArgumentCount<Functor,
     616             :             typename List_Left<List<First, ArgList...>, sizeof...(ArgList)>::Value> {};
     617             : 
     618             :     template <typename Functor, typename... ArgList> struct ComputeFunctorArgumentCount<Functor, List<ArgList...>>
     619             :     {
     620             :         template <typename D> static D dummy();
     621             :         template <typename F> static auto test(F f) -> decltype(((f.operator()((dummy<ArgList>())...)), int()));
     622             :         static char test(...);
     623             :         enum {
     624             :             Ok = sizeof(test(dummy<Functor>())) == sizeof(int),
     625             :             Value = Ok ? int(sizeof...(ArgList)) : int(ComputeFunctorArgumentCountHelper<Functor, List<ArgList...>, Ok>::Value)
     626             :         };
     627             :     };
     628             : 
     629             :     /* get the return type of a functor, given the signal argument list  */
     630             :     template <typename Functor, typename ArgList> struct FunctorReturnType;
     631             :     template <typename Functor, typename ... ArgList> struct FunctorReturnType<Functor, List<ArgList...>> {
     632             :         template <typename D> static D dummy();
     633             :         typedef decltype(dummy<Functor>().operator()((dummy<ArgList>())...)) Value;
     634             :     };
     635             : #endif
     636             : 
     637             : }
     638             : 
     639             : QT_END_NAMESPACE
     640             : 
     641             : #endif

Generated by: LCOV version 1.11