1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QPROMISE_H
41#define QPROMISE_H
42
43#include <QtCore/qglobal.h>
44#include <QtCore/qfuture.h>
45
46#include <utility>
47
48QT_REQUIRE_CONFIG(future);
49
50QT_BEGIN_NAMESPACE
51
52template<typename T>
53class QPromise
54{
55 static_assert (std::is_copy_constructible_v<T>
56 || std::is_move_constructible_v<T>
57 || std::is_same_v<T, void>,
58 "Type with copy or move constructors or type void is required");
59public:
60 QPromise() = default;
61 Q_DISABLE_COPY(QPromise)
62 QPromise(QPromise<T> &&other) : d(other.d)
63 {
64 other.d = QFutureInterface<T>();
65 }
66 QPromise(QFutureInterface<T> &other) : d(other) {}
67 QPromise& operator=(QPromise<T> &&other)
68 {
69 QPromise<T> tmp(std::move(other));
70 tmp.swap(*this);
71 return *this;
72 }
73 ~QPromise()
74 {
75 const int state = d.loadState();
76 // If QFutureInterface has no state, there is nothing to be done
77 if (state == static_cast<int>(QFutureInterfaceBase::State::NoState))
78 return;
79 // Otherwise, if computation is not finished at this point, cancel
80 // potential waits
81 if (!(state & QFutureInterfaceBase::State::Finished)) {
82 d.cancel();
83 finish(); // required to finalize the state
84 }
85 }
86
87 // Core QPromise APIs
88 QFuture<T> future() const { return d.future(); }
89 template<typename U, typename = QtPrivate::EnableIfSameOrConvertible<U, T>>
90 bool addResult(U &&result, int index = -1)
91 {
92 return d.reportResult(std::forward<U>(result), index);
93 }
94#ifndef QT_NO_EXCEPTIONS
95 void setException(const QException &e) { d.reportException(e); }
96 void setException(std::exception_ptr e) { d.reportException(e); }
97#endif
98 void start() { d.reportStarted(); }
99 void finish() { d.reportFinished(); }
100
101 void suspendIfRequested() { d.suspendIfRequested(); }
102
103 bool isCanceled() const { return d.isCanceled(); }
104
105 // Progress methods
106 void setProgressRange(int minimum, int maximum) { d.setProgressRange(minimum, maximum); }
107 void setProgressValue(int progressValue) { d.setProgressValue(progressValue); }
108 void setProgressValueAndText(int progressValue, const QString &progressText)
109 {
110 d.setProgressValueAndText(progressValue, progressText);
111 }
112
113 void swap(QPromise<T> &other) noexcept
114 {
115 qSwap(this->d, other.d);
116 }
117
118#if defined(Q_CLANG_QDOC) // documentation-only simplified signatures
119 bool addResult(const T &result, int index = -1) { }
120 bool addResult(T &&result, int index = -1) { }
121#endif
122private:
123 mutable QFutureInterface<T> d = QFutureInterface<T>();
124};
125
126template<typename T>
127inline void swap(QPromise<T> &a, QPromise<T> &b) noexcept
128{
129 a.swap(b);
130}
131
132QT_END_NAMESPACE
133
134#endif // QPROMISE_H
135