libquentier 0.8.0
The library for rich desktop clients of Evernote service
Loading...
Searching...
No Matches
Qt5Promise.h
1/*
2 * Copyright 2021-2024 Dmitry Ivanov
3 *
4 * This file is part of libquentier
5 *
6 * libquentier is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, version 3 of the License.
9 *
10 * libquentier is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with libquentier. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <QFutureInterface>
22
23#include <type_traits>
24
25// Partial backport of QPromise from Qt6 to Qt5
26template <typename T>
28{
29 static_assert(
30 std::is_copy_constructible_v<T> || std::is_move_constructible_v<T> ||
31 std::is_same_v<T, void>,
32 "Type with copy or move constructors or type void is required");
33
34public:
35 QPromise() = default;
36
37 Q_DISABLE_COPY(QPromise)
38
39 QPromise(QPromise<T> && other) noexcept : d(other.d)
40 {
41 other.d = QFutureInterface<T>();
42 }
43
44 QPromise(QFutureInterface<T> & other) : d(other) {}
45
46 QPromise & operator=(QPromise<T> && other) noexcept
47 {
48 QPromise<T> tmp(std::move(other));
49 tmp.swap(*this);
50 return *this;
51 }
52
53 ~QPromise()
54 {
55 // If QFutureInterface has no state, there is nothing to be done
56 if (d.queryState(QFutureInterfaceBase::State::NoState)) {
57 return;
58 }
59
60 // Otherwise, if computation is not finished at this point, cancel
61 // potential waits
62 if (!d.queryState(QFutureInterfaceBase::State::Finished)) {
63 d.cancel();
64 finish(); // required to finalize the state
65 }
66 }
67
68 // Core QPromise APIs
69 QFuture<T> future() const
70 {
71 return d.future();
72 }
73 template <
74 typename U,
75 typename = std::enable_if_t<
76 std::is_same_v<U, T> || std::is_convertible_v<U, T>>>
77 void addResult(U && result, int index = -1)
78 {
79 d.reportResult(std::forward<U>(result), index);
80 }
81
82 void setException(const QException & e)
83 {
84 d.reportException(e);
85 }
86
87 void start()
88 {
89 d.reportStarted();
90 }
91 void finish()
92 {
93 d.reportFinished();
94 }
95
96 void suspendIfRequested()
97 {
98 d.suspendIfRequested();
99 }
100
101 bool isCanceled() const
102 {
103 return d.isCanceled();
104 }
105
106 // Progress methods
107 void setProgressRange(int minimum, int maximum)
108 {
109 d.setProgressRange(minimum, maximum);
110 }
111 void setProgressValue(int progressValue)
112 {
113 d.setProgressValue(progressValue);
114 }
115 void setProgressValueAndText(
116 int progressValue, const QString & progressText)
117 {
118 d.setProgressValueAndText(progressValue, progressText);
119 }
120
121 void swap(QPromise<T> & other) noexcept
122 {
123 qSwap(this->d, other.d);
124 }
125
126private:
127 mutable QFutureInterface<T> d = QFutureInterface<T>();
128};
129
130template <typename T>
131inline void swap(QPromise<T> & a, QPromise<T> & b) noexcept
132{
133 a.swap(b);
134}
Definition Qt5Promise.h:28