File indexing completed on 2024-05-19 05:37:25
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 "../cxxutils_p.h" 0019 #include "../utils_p.h" 0020 0021 namespace AsynQt 0022 { 0023 namespace detail 0024 { 0025 template<typename... _Results> 0026 class CollectFutureInterface : public QObject, public QFutureInterface<std::tuple<_Results...>> 0027 { 0028 public: 0029 CollectFutureInterface(QFuture<_Results>... futures) 0030 : m_waitingCount(m_count) 0031 , m_futures(std::make_tuple(futures...)) 0032 { 0033 } 0034 0035 template<int index> 0036 bool connectFuture() 0037 { 0038 auto future = std::get<index>(m_futures); 0039 auto &watcher = std::get<index>(m_watchers); 0040 0041 onFinished(watcher, [this] { 0042 m_waitingCount--; 0043 0044 // We are saving the result 0045 std::get<index>(m_results) = std::get<index>(m_futures).result(); 0046 0047 // If all futures are done, report the result 0048 if (m_waitingCount == 0) { 0049 this->reportResult(m_results); 0050 this->reportFinished(); 0051 } 0052 }); 0053 0054 onCanceled(watcher, [this] { 0055 // If any of the futures fail, we can not return 0056 // the result :( 0057 this->reportCanceled(); 0058 }); 0059 0060 watcher.setFuture(future); 0061 0062 return true; 0063 } 0064 0065 template<int... Indices> 0066 void connectFutures(index_sequence<Indices...>) 0067 { 0068 auto ignore = {connectFuture<Indices>()...}; 0069 Q_UNUSED(ignore); 0070 } 0071 0072 QFuture<std::tuple<_Results...>> start() 0073 { 0074 // we need to call connectFuture for index = 0 to sizeof..._Results 0075 connectFutures(make_index_sequence<m_count>()); 0076 0077 this->reportStarted(); 0078 0079 return this->future(); 0080 } 0081 0082 private: 0083 static const constexpr std::size_t m_count = sizeof...(_Results); 0084 int m_waitingCount; 0085 std::tuple<QFuture<_Results>...> m_futures; 0086 std::tuple<QFutureWatcher<_Results>...> m_watchers; 0087 std::tuple<_Results...> m_results; 0088 }; 0089 0090 template<typename... _Results> 0091 QFuture<std::tuple<_Results...>> collect_impl(QFuture<_Results>... futures) 0092 { 0093 return (new CollectFutureInterface<_Results...>(futures...))->start(); 0094 } 0095 0096 } // namespace detail 0097 } // namespace AsynQt