libquentier 0.8.0
The library for rich desktop clients of Evernote service
Loading...
Searching...
No Matches
QtFutureHelpers.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 <QFuture>
22
23#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
24#include "Qt5Promise.h"
25#endif
26
27#include <type_traits>
28
29#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
30// Backports of some helpers for QFuture continuations from Qt6 to Qt5
31namespace QtFuture {
32
33// Inherit option from Qt6 is not supported in Qt5
34enum class Launch
35{
36 Sync,
37 Async,
38};
39
40} // namespace QtFuture
41
42namespace QtPrivate {
43
44template <typename...>
45struct ArgsType;
46
47template <typename Arg, typename... Args>
48struct ArgsType<Arg, Args...>
49{
50 using First = Arg;
51 using PromiseType = void;
52 using IsPromise = std::false_type;
53 static const bool HasExtraArgs = (sizeof...(Args) > 0);
54
55 template <class Class, class Callable>
56 static const bool CanInvokeWithArgs =
57 std::is_invocable_v<Callable, Class, Arg, Args...>;
58};
59
60template <typename Arg, typename... Args>
61struct ArgsType<QPromise<Arg> &, Args...>
62{
63 using First = QPromise<Arg> &;
64 using PromiseType = Arg;
65 using IsPromise = std::true_type;
66 static const bool HasExtraArgs = (sizeof...(Args) > 0);
67
68 template <class Class, class Callable>
69 static const bool CanInvokeWithArgs =
70 std::is_invocable_v<Callable, Class, QPromise<Arg> &, Args...>;
71};
72
73template <>
74struct ArgsType<>
75{
76 using First = void;
77 using PromiseType = void;
78 using IsPromise = std::false_type;
79 static const bool HasExtraArgs = false;
80 using AllArgs = void;
81
82 template <class Class, class Callable>
83 static const bool CanInvokeWithArgs = std::is_invocable_v<Callable, Class>;
84};
85
86template <typename F>
87struct ArgResolver : ArgResolver<decltype(&std::decay_t<F>::operator())>
88{};
89
90template <typename F>
91struct ArgResolver<std::reference_wrapper<F>> :
92 ArgResolver<decltype(&std::decay_t<F>::operator())>
93{};
94
95template <typename R, typename... Args>
96struct ArgResolver<R(Args...)> : public ArgsType<Args...>
97{};
98
99template <typename R, typename... Args>
100struct ArgResolver<R (*)(Args...)> : public ArgsType<Args...>
101{};
102
103template <typename R, typename... Args>
104struct ArgResolver<R (*&)(Args...)> : public ArgsType<Args...>
105{};
106
107template <typename R, typename... Args>
108struct ArgResolver<R (*const)(Args...)> : public ArgsType<Args...>
109{};
110
111template <typename R, typename... Args>
112struct ArgResolver<R (&)(Args...)> : public ArgsType<Args...>
113{};
114
115template <typename Class, typename R, typename... Args>
116struct ArgResolver<R (Class::*)(Args...)> : public ArgsType<Args...>
117{};
118
119template <typename Class, typename R, typename... Args>
120struct ArgResolver<R (Class::*)(Args...) noexcept> : public ArgsType<Args...>
121{};
122
123template <typename Class, typename R, typename... Args>
124struct ArgResolver<R (Class::*)(Args...) const> : public ArgsType<Args...>
125{};
126
127template <typename Class, typename R, typename... Args>
128struct ArgResolver<R (Class::*)(Args...) const noexcept> :
129 public ArgsType<Args...>
130{};
131
132template <typename Class, typename R, typename... Args>
133struct ArgResolver<R (Class::*const)(Args...) const> : public ArgsType<Args...>
134{};
135
136template <typename Class, typename R, typename... Args>
137struct ArgResolver<R (Class::*const)(Args...) const noexcept> :
138 public ArgsType<Args...>
139{};
140
141} // namespace QtPrivate
142#endif // QT_VERSION
143
144namespace quentier::threading::detail {
145
146template <typename F, typename Arg, typename Enable = void>
148{};
149
150// The callable takes an argument of type Arg
151template <typename F, typename Arg>
153 F, Arg,
155 !std::is_invocable_v<std::decay_t<F>, QFuture<Arg>>>>
156{
157 using ResultType = std::invoke_result_t<std::decay_t<F>, std::decay_t<Arg>>;
158};
159
160// The callable takes an argument of type QFuture<Arg>
161template <class F, class Arg>
163 F, Arg,
165 std::is_invocable_v<std::decay_t<F>, QFuture<Arg>>>>
166{
167 using ResultType = std::invoke_result_t<std::decay_t<F>, QFuture<Arg>>;
168};
169
170// The callable takes an argument of type QFuture<void>
171template <class F>
173 F, void,
175 std::is_invocable_v<std::decay_t<F>, QFuture<void>>>>
176{
177 using ResultType = std::invoke_result_t<std::decay_t<F>, QFuture<void>>;
178};
179
180// The callable doesn't take argument
181template <class F>
183 F, void,
185 !std::is_invocable_v<std::decay_t<F>, QFuture<void>>>>
186{
187 using ResultType = std::invoke_result_t<std::decay_t<F>>;
188};
189
190} // namespace quentier::threading::detail
Definition Qt5Promise.h:28
The Result template class represents the bare bones result monad implementation which either contains...
Definition Result.h:38
Definition QtFutureHelpers.h:148