File indexing completed on 2024-05-19 05:37:25

0001 /*
0002  *   SPDX-FileCopyrightText: 2016 Ivan Cukic <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 <type_traits>
0019 
0020 #include "../utils_p.h"
0021 
0022 namespace AsynQt
0023 {
0024 namespace detail
0025 {
0026 template<typename _Type, typename _Predicate>
0027 class FilterFutureInterface : public QObject, public QFutureInterface<_Type>
0028 {
0029 public:
0030     FilterFutureInterface(QFuture<_Type> future, _Predicate predicate)
0031         : m_future(future)
0032         , m_predicate(predicate)
0033     {
0034     }
0035 
0036     QFuture<_Type> start()
0037     {
0038         m_futureWatcher.reset(new QFutureWatcher<_Type>());
0039 
0040         onFinished(m_futureWatcher, [this]() {
0041             this->reportFinished();
0042         });
0043 
0044         onCanceled(m_futureWatcher, [this]() {
0045             this->reportCanceled();
0046         });
0047 
0048         onResultReadyAt(m_futureWatcher, [this](int index) {
0049             auto result = m_future.resultAt(index);
0050             if (m_predicate(result)) {
0051                 this->reportResult(result);
0052             }
0053         });
0054 
0055         m_futureWatcher->setFuture(m_future);
0056 
0057         this->reportStarted();
0058 
0059         return this->future();
0060     }
0061 
0062 private:
0063     QFuture<_Type> m_future;
0064     _Predicate m_predicate;
0065     std::unique_ptr<QFutureWatcher<_Type>> m_futureWatcher;
0066 };
0067 
0068 template<typename _Type, typename _Predicate>
0069 QFuture<_Type> filter_impl(const QFuture<_Type> &future, _Predicate &&predicate)
0070 {
0071     return (new FilterFutureInterface<_Type, _Predicate>(future, std::forward<_Predicate>(predicate)))->start();
0072 }
0073 
0074 namespace operators
0075 {
0076 template<typename _Predicate>
0077 class FilterModifier
0078 {
0079 public:
0080     FilterModifier(_Predicate predicate)
0081         : m_predicate(predicate)
0082     {
0083     }
0084 
0085     _Predicate m_predicate;
0086 };
0087 
0088 template<typename _Type, typename _Predicate>
0089 auto operator|(const QFuture<_Type> &future, FilterModifier<_Predicate> &&modifier) -> decltype(filter_impl(future, modifier.m_predicate))
0090 {
0091     return filter_impl(future, modifier.m_predicate);
0092 }
0093 
0094 } // namespace operators
0095 
0096 } // namespace detail
0097 } // namespace AsynQt