123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 | // Copyright (C) 2016 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndef QTCONCURRENT_FUNCTIONWRAPPERS_H#define QTCONCURRENT_FUNCTIONWRAPPERS_H#include <QtConcurrent/qtconcurrentcompilertest.h>#include <QtConcurrent/qtconcurrentreducekernel.h>#include <QtCore/qfuture.h>#include <tuple>#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC) QT_BEGIN_NAMESPACE namespace QtPrivate {struct PushBackWrapper {template<class C,class U>inlinevoidoperator()(C &c,const U &u)const{return c.push_back(u);}template<class C,class U>inlinevoidoperator()(C &c, U &&u)const{return c.push_back(u);}};// -- MapResultTypetemplate<class T,class Enable =void>struct Argument {using Type =void;};template<class Sequence>struct Argument<Sequence, typename std::enable_if<IsIterableValue<Sequence>>::type>{using Type =std::decay_t<decltype(*std::declval<Sequence>().begin())>;};template<class Iterator>struct Argument<Iterator, typename std::enable_if<IsDereferenceableValue<Iterator>>::type>{using Type =std::decay_t<decltype(*std::declval<Iterator>())>;};template<class T>using ArgumentType = typename Argument<T>::Type;template<class T,class MapFunctor>struct MapResult {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<class T,class MapFunctor>using MapResultType = typename MapResult<T, MapFunctor>::Type;// -- ReduceResultTypetemplate<class T>struct ReduceResultType;template<class U,class V>struct ReduceResultType<void(*)(U&,V)>{using ResultType = U;};template<class T,class C,class U>struct ReduceResultType<T(C::*)(U)>{using ResultType = C;};template<class U,class V>struct ReduceResultType<std::function<void(U&, V)>>{using ResultType = U;};template<typename R, typename ...A>struct ReduceResultType<R(*)(A...)>{using ResultType = typename std::tuple_element<0,std::tuple<A...>>::type;};template<class U,class V>struct ReduceResultType<void(*)(U&,V) noexcept>{using ResultType = U;};template<class T,class C,class U>struct ReduceResultType<T(C::*)(U) noexcept>{using ResultType = C;};template<class T,class Enable =void>inline constexprbool hasCallOperator_v =false;template<class T>inline constexprbool hasCallOperator_v<T,std::void_t<decltype(&T::operator())>> =true;template<class T,class Enable =void>inline constexprbool isIterator_v =false;template<class T>inline constexprbool isIterator_v<T,std::void_t<typename std::iterator_traits<T>::value_type>> =true;template<class Callable,class Sequence>using isInvocable =std::is_invocable<Callable, typename std::decay_t<Sequence>::value_type>;template<class InitialValueType,class ResultType>inline constexprbool isInitialValueCompatible_v =std::conjunction_v<std::is_convertible<InitialValueType, ResultType>,std::negation<std::is_same<std::decay_t<InitialValueType>,QtConcurrent::ReduceOption>>>;template<class Callable,class Enable =void>struct ReduceResultTypeHelper {};template<class Callable>struct ReduceResultTypeHelper<Callable, typename std::enable_if_t<std::is_function_v<std::remove_pointer_t<std::decay_t<Callable>>>||std::is_member_function_pointer_v<std::decay_t<Callable>>>>{using type = typename QtPrivate::ReduceResultType<std::decay_t<Callable>>::ResultType;};template<class Callable>struct ReduceResultTypeHelper<Callable, typename std::enable_if_t<!std::is_function_v<std::remove_pointer_t<std::decay_t<Callable>>>&& hasCallOperator_v<std::decay_t<Callable>>>>{using type =std::decay_t<typename QtPrivate::ArgResolver<Callable>::First>;};// -- MapSequenceResultTypetemplate<class InputSequence,class MapFunctor>struct MapSequenceResultType {static_assert(std::is_same_v<typename InputSequence::value_type,QtPrivate::MapResultType<InputSequence, MapFunctor>>,"Couldn't deduce the output sequence type, you must specify it explicitly.");typedef InputSequence ResultType;};#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERStemplate<template<typename...>class InputSequence, typename MapFunctor, typename ...T>struct MapSequenceResultType<InputSequence<T...>, MapFunctor>{typedef InputSequence<QtPrivate::MapResultType<InputSequence<T...>, MapFunctor>> ResultType;};#endif// QT_NO_TEMPLATE_TEMPLATE_PARAMETER}// namespace QtPrivate. QT_END_NAMESPACE #endif// QT_NO_CONCURRENT#endif
|