summaryrefslogtreecommitdiffstats
path: root/src/concurrent/qtconcurrentfunctionwrappers.h
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@qt.io>2020-03-26 15:47:04 +0100
committerKarsten Heimrich <karsten.heimrich@qt.io>2020-04-14 19:06:27 +0200
commit786b48878f37edafd5eb928ed0f4d046ee1d6bec (patch)
tree7dffd263964b1375dd9814d4edcfc675d7489e84 /src/concurrent/qtconcurrentfunctionwrappers.h
parent678b9f78a5af4513ed4e988de90148584a2ae90d (diff)
Improve Map|Map-Reduce and Filter|Filter-Reduce implementation
* support lambda expressions * remove the need to specify result_type * use std::invoke to apply map|filter function * remove usage of FunctionWrapper* and createFunctionWrapper Task-number: QTBUG-33735 Task-number: QTBUG-82646 Change-Id: Ibcbe4278f0742c29182bd506081db0abb516f85f Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Diffstat (limited to 'src/concurrent/qtconcurrentfunctionwrappers.h')
-rw-r--r--src/concurrent/qtconcurrentfunctionwrappers.h272
1 files changed, 51 insertions, 221 deletions
diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h
index 4731de77cc..34bbe89c86 100644
--- a/src/concurrent/qtconcurrentfunctionwrappers.h
+++ b/src/concurrent/qtconcurrentfunctionwrappers.h
@@ -43,165 +43,64 @@
#include <QtConcurrent/qtconcurrentcompilertest.h>
#include <QtCore/QStringList>
+#include <tuple>
+
#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
QT_BEGIN_NAMESPACE
-namespace QtConcurrent {
+namespace QtPrivate {
-template <typename T, typename U>
-class FunctionWrapper1
+struct PushBackWrapper
{
-public:
- typedef T (*FunctionPointerType)(U u);
- typedef T result_type;
- inline FunctionWrapper1(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
-
- inline T operator()(U u)
+ template <class C, class U>
+ inline void operator()(C &c, const U &u) const
{
- return functionPointer(u);
+ return c.push_back(u);
}
-private:
- FunctionPointerType functionPointer;
-};
-
-template <typename T, typename C>
-class MemberFunctionWrapper
-{
-public:
- typedef T (C::*FunctionPointerType)();
- typedef T result_type;
- inline MemberFunctionWrapper(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
-
- inline T operator()(C &c)
+ template <class C, class U>
+ inline void operator()(C &c, U &&u) const
{
- return (c.*functionPointer)();
+ return c.push_back(u);
}
-private:
- FunctionPointerType functionPointer;
};
-template <typename T, typename C, typename U>
-class MemberFunctionWrapper1
-{
-public:
- typedef T (C::*FunctionPointerType)(U);
- typedef T result_type;
-
- inline MemberFunctionWrapper1(FunctionPointerType _functionPointer)
- : functionPointer(_functionPointer)
- { }
-
- inline T operator()(C &c, U u)
- {
- return (c.*functionPointer)(u);
- }
-
-private:
- FunctionPointerType functionPointer;
-};
+// -- MapResultType
-template <typename T, typename C>
-class ConstMemberFunctionWrapper
+template <class T, class Enable = void>
+struct Argument
{
-public:
- typedef T (C::*FunctionPointerType)() const;
- typedef T result_type;
- inline ConstMemberFunctionWrapper(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
-
- inline T operator()(const C &c) const
- {
- return (c.*functionPointer)();
- }
-private:
- FunctionPointerType functionPointer;
+ using Type = void;
};
-} // namespace QtConcurrent.
-
-namespace QtPrivate {
-
-template <typename T>
-const T& createFunctionWrapper(const T& t)
+template <class Sequence>
+struct Argument<Sequence, typename std::enable_if<IsIterableValue<Sequence>>::type>
{
- return t;
-}
-
-template <typename T, typename U>
-QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U))
-{
- return QtConcurrent::FunctionWrapper1<T, U>(func);
-}
-
-template <typename T, typename C>
-QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)())
-{
- return QtConcurrent::MemberFunctionWrapper<T, C>(func);
-}
-
-template <typename T, typename C, typename U>
-QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U))
-{
- return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func);
-}
-
-template <typename T, typename C>
-QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const)
-{
- return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func);
-}
-
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename U>
-QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U) noexcept)
-{
- return QtConcurrent::FunctionWrapper1<T, U>(func);
-}
+ using Type = std::decay_t<decltype(*std::begin(std::declval<Sequence>()))>;
+};
-template <typename T, typename C>
-QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() noexcept)
+template <class Iterator>
+struct Argument<Iterator, typename std::enable_if<IsDereferenceableValue<Iterator>>::type>
{
- return QtConcurrent::MemberFunctionWrapper<T, C>(func);
-}
+ using Type = std::decay_t<decltype(*std::declval<Iterator>())>;
+};
-template <typename T, typename C, typename U>
-QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U) noexcept)
-{
- return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func);
-}
+template <class T>
+using ArgumentType = typename Argument<T>::Type;
-template <typename T, typename C>
-QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const noexcept)
+template <class T, class MapFunctor>
+struct MapResult
{
- return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func);
-}
-#endif
-
-struct PushBackWrapper
-{
- typedef void result_type;
-
- template <class C, class U>
- inline void operator()(C &c, const U &u) const
- {
- return c.push_back(u);
- }
-
- template <class C, class U>
- inline void operator()(C &c, U &&u) const
- {
- return c.push_back(u);
- }
+ static_assert(std::is_invocable_v<std::decay_t<MapFunctor>, ArgumentType<T>>,
+ "It's not possible to invoke the function with passed argument.");
+ using Type = std::invoke_result_t<std::decay_t<MapFunctor>, ArgumentType<T>>;
};
-template <typename Functor, bool foo = HasResultType<Functor>::Value>
-struct LazyResultType { typedef typename Functor::result_type Type; };
-template <typename Functor>
-struct LazyResultType<Functor, false> { typedef void Type; };
+template <class T, class MapFunctor>
+using MapResultType = typename MapResult<T, MapFunctor>::Type;
+
+// -- ReduceResultType
template <class T>
struct ReduceResultType;
@@ -218,121 +117,52 @@ struct ReduceResultType<T(C::*)(U)>
typedef C ResultType;
};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <class U, class V>
-struct ReduceResultType<void(*)(U&,V) noexcept>
-{
- typedef U ResultType;
-};
-
-template <class T, class C, class U>
-struct ReduceResultType<T(C::*)(U) noexcept>
-{
- typedef C ResultType;
-};
-#endif
-
-template <class InputSequence, class MapFunctor>
-struct MapResultType
-{
- typedef typename LazyResultType<MapFunctor>::Type ResultType;
-};
-
template <class U, class V>
-struct MapResultType<void, U (*)(V)>
+struct ReduceResultType<std::function<void(U&, V)>>
{
typedef U ResultType;
};
-template <class T, class C>
-struct MapResultType<void, T(C::*)() const>
+template <typename R, typename ...A>
+struct ReduceResultType<R(*)(A...)>
{
- typedef T ResultType;
+ using ResultType = typename std::tuple_element<0, std::tuple<A...>>::type;
};
#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
template <class U, class V>
-struct MapResultType<void, U (*)(V) noexcept>
+struct ReduceResultType<void(*)(U&,V) noexcept>
{
typedef U ResultType;
};
-template <class T, class C>
-struct MapResultType<void, T(C::*)() const noexcept>
+template <class T, class C, class U>
+struct ReduceResultType<T(C::*)(U) noexcept>
{
- typedef T ResultType;
+ typedef C ResultType;
};
#endif
-#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
-
-template <template <typename> class InputSequence, typename MapFunctor, typename T>
-struct MapResultType<InputSequence<T>, MapFunctor>
-{
- typedef InputSequence<typename LazyResultType<MapFunctor>::Type> ResultType;
-};
-
-template <template <typename> class InputSequence, class T, class U, class V>
-struct MapResultType<InputSequence<T>, U (*)(V)>
-{
- typedef InputSequence<U> ResultType;
-};
+// -- MapSequenceResultType
-template <template <typename> class InputSequence, class T, class U, class C>
-struct MapResultType<InputSequence<T>, U(C::*)() const>
-{
- typedef InputSequence<U> ResultType;
-};
-
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-
-template <template <typename> class InputSequence, class T, class U, class V>
-struct MapResultType<InputSequence<T>, U (*)(V) noexcept>
-{
- typedef InputSequence<U> ResultType;
-};
-
-template <template <typename> class InputSequence, class T, class U, class C>
-struct MapResultType<InputSequence<T>, U(C::*)() const noexcept>
-{
- typedef InputSequence<U> ResultType;
-};
-#endif
-
-#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER
+template <class InputSequence, class MapFunctor>
+struct MapSequenceResultType;
template <class MapFunctor>
-struct MapResultType<QStringList, MapFunctor>
+struct MapSequenceResultType<QStringList, MapFunctor>
{
- typedef QList<typename LazyResultType<MapFunctor>::Type> ResultType;
+ typedef QList<QtPrivate::MapResultType<QStringList, MapFunctor>> ResultType;
};
-template <class U, class V>
-struct MapResultType<QStringList, U (*)(V)>
-{
- typedef QList<U> ResultType;
-};
-
-template <class U, class C>
-struct MapResultType<QStringList, U(C::*)() const>
-{
- typedef QList<U> ResultType;
-};
-
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
+#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
-template <class U, class V>
-struct MapResultType<QStringList, U (*)(V) noexcept>
+template <template <typename> class InputSequence, typename MapFunctor, typename T>
+struct MapSequenceResultType<InputSequence<T>, MapFunctor>
{
- typedef QList<U> ResultType;
+ typedef InputSequence<QtPrivate::MapResultType<InputSequence<T>, MapFunctor>> ResultType;
};
-template <class U, class C>
-struct MapResultType<QStringList, U(C::*)() const noexcept>
-{
- typedef QList<U> ResultType;
-};
-#endif
+#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER
} // namespace QtPrivate.