File indexing completed on 2024-05-12 17:08:32
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Ivan Čukić <ivan.cukic(at)kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 // 0008 // W A R N I N G 0009 // ------------- 0010 // 0011 // This file is not part of the AsynQt API. It exists purely as an 0012 // implementation detail. This header file may change from version to 0013 // version without notice, or even be removed. 0014 // 0015 // We mean it. 0016 // 0017 0018 #include "../utils_p.h" 0019 0020 namespace AsynQt 0021 { 0022 namespace detail 0023 { 0024 template<typename T> 0025 struct isNullary { 0026 private: 0027 template<typename U> 0028 static decltype(std::declval<U>()(), std::true_type()) test(int); 0029 0030 template<typename> 0031 static std::false_type test(...); 0032 0033 public: 0034 typedef decltype(test<T>(0)) type; 0035 enum { value = type::value }; 0036 }; 0037 0038 template<typename _Function> 0039 class PassResult 0040 { 0041 private: 0042 using isNullaryFunction = typename isNullary<_Function>::type; 0043 _Function m_function; 0044 0045 template<typename _Result> 0046 void callFunction(const QFuture<_Result> &future, std::true_type) const 0047 { 0048 Q_UNUSED(future); 0049 if (!future.isCanceled()) { 0050 m_function(); 0051 } 0052 } 0053 0054 template<typename _Result> 0055 void callFunction(const QFuture<_Result> &future, std::false_type) const 0056 { 0057 if (future.resultCount()) { 0058 m_function(future.result()); 0059 } 0060 } 0061 0062 public: 0063 PassResult(_Function function) 0064 : m_function(function) 0065 { 0066 } 0067 0068 template<typename _Result> 0069 void operator()(const QFuture<_Result> &future) const 0070 { 0071 callFunction(future, isNullaryFunction()); 0072 } 0073 }; 0074 0075 template<typename _Function> 0076 class PassError 0077 { 0078 public: 0079 PassError(_Function function) 0080 : m_function(function) 0081 { 0082 } 0083 0084 template<typename _Result> 0085 void operator()(const QFuture<_Result> &future) const 0086 { 0087 if (future.isCanceled()) { 0088 m_function(); 0089 } 0090 } 0091 0092 private: 0093 _Function m_function; 0094 }; 0095 0096 template<typename _Type, typename _Function> 0097 QFuture<_Type> onFinished_impl(const QFuture<_Type> &future, _Function &&function) 0098 { 0099 auto watcher = new QFutureWatcher<_Type>(); 0100 QObject::connect(watcher, &QFutureWatcherBase::finished, [watcher, function]() { 0101 function(watcher->future()); 0102 watcher->deleteLater(); 0103 }); 0104 watcher->setFuture(future); 0105 0106 return future; 0107 } 0108 0109 namespace operators 0110 { 0111 template<typename _Function> 0112 class OnFinishedModifier 0113 { 0114 public: 0115 OnFinishedModifier(_Function function) 0116 : m_function(function) 0117 { 0118 } 0119 0120 _Function m_function; 0121 }; 0122 0123 template<typename _Type, typename _Function> 0124 auto operator|(const QFuture<_Type> &future, OnFinishedModifier<_Function> &&modifier) -> decltype(onFinished_impl(future, modifier.m_function)) 0125 { 0126 return onFinished_impl(future, modifier.m_function); 0127 } 0128 0129 } // namespace operators 0130 0131 } // namespace detail 0132 } // namespace AsynQt