diff options
author | Olivier Goffart <ogoffart@woboq.com> | 2013-03-01 10:18:36 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-19 23:16:38 +0100 |
commit | bc98bba2f302922761209c0e91485e809354abc1 (patch) | |
tree | 82854fc70dd695c27abe9bbe8c61d07e9b8f314d /src/corelib/kernel/qobjectdefs_impl.h | |
parent | e66159cfc7f78b8ad617175bbef6b70edbf9da6b (diff) |
Support connection to functor with multiple operator()
When variadic templates and decltype are supported, detect the best
overload of operator() to call.
Currently, the code takes the type of the operator(), which requires that
the functor only has one, and that it has no template parameter.
This feature is required if we want to connect to c++1y generic lambda
(N3418)
Change-Id: Ifa957da6955ea39ab804b58f320da9f98ff47d63
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
Diffstat (limited to 'src/corelib/kernel/qobjectdefs_impl.h')
-rw-r--r-- | src/corelib/kernel/qobjectdefs_impl.h | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 46a6eab253..4f44d9204e 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -597,10 +598,43 @@ namespace QtPrivate { enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value && CheckCompatibleArguments<List<Tail1...>, List<Tail2...>>::value }; }; +#endif + +#if defined(Q_COMPILER_DECLTYPE) && defined(Q_COMPILER_VARIADIC_TEMPLATES) + /* + Find the maximum number of arguments a functor object can take and be still compatible with + the arguments from the signal. + Value is the number of arguments, or -1 if nothing matches. + */ + template <typename Functor, typename ArgList> struct ComputeFunctorArgumentCount; + + template <typename Functor, typename ArgList, bool Done> struct ComputeFunctorArgumentCountHelper + { enum { Value = -1 }; }; + template <typename Functor, typename First, typename... ArgList> + struct ComputeFunctorArgumentCountHelper<Functor, List<First, ArgList...>, false> + : ComputeFunctorArgumentCount<Functor, + typename List_Left<List<First, ArgList...>, sizeof...(ArgList)>::Value> {}; + + template <typename Functor, typename... ArgList> struct ComputeFunctorArgumentCount<Functor, List<ArgList...>> + { + template <typename D> static D dummy(); + template <typename F> static auto test(F f) -> decltype(((f.operator()((dummy<ArgList>())...)), int())); + static char test(...); + enum { + Ok = sizeof(test(dummy<Functor>())) == sizeof(int), + Value = Ok ? sizeof...(ArgList) : int(ComputeFunctorArgumentCountHelper<Functor, List<ArgList...>, Ok>::Value) + }; + }; + /* get the return type of a functor, given the signal argument list */ + template <typename Functor, typename ArgList> struct FunctorReturnType; + template <typename Functor, typename ... ArgList> struct FunctorReturnType<Functor, List<ArgList...>> { + template <typename D> static D dummy(); + typedef decltype(dummy<Functor>().operator()((dummy<ArgList>())...)) Value; + }; #endif -} +} QT_END_NAMESPACE |