Directory: | ./ |
---|---|
File: | QtPdCom1/FutureWatchersDetails.h |
Date: | 2024-11-19 17:00:39 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 3 | 3 | 100.0% |
Branches: | 4 | 8 | 50.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /***************************************************************************** | ||
2 | * | ||
3 | * Copyright (C) 2009 - 2022 Bjarne von Horn <vh@igh.de> | ||
4 | * | ||
5 | * This file is part of the QtPdCom library. | ||
6 | * | ||
7 | * The QtPdCom library is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as published by | ||
9 | * the Free Software Foundation, either version 3 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | * The QtPdCom library is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
15 | * License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public License | ||
18 | * along with the QtPdCom Library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | |||
23 | #ifndef QTPDCOM_FUTUREWATCHERS_DETAILS_H | ||
24 | #define QTPDCOM_FUTUREWATCHERS_DETAILS_H | ||
25 | |||
26 | #include <QFutureWatcher> | ||
27 | |||
28 | #include <type_traits> | ||
29 | |||
30 | namespace QtPdCom { namespace details { | ||
31 | |||
32 | template <class T> using void_t = void; | ||
33 | |||
34 | template <class Obj, class... Arg> struct takes_obj_as_first_parameter_i | ||
35 | { | ||
36 | template <class Func> static bool value(...) | ||
37 | { | ||
38 | throw "argument mismatch. Make sure that your callback takes " | ||
39 | "(optionally) a reference to Object as first argument " | ||
40 | "and the result of the Future (if it is non-void) as value or " | ||
41 | "const reference as the other argument"; | ||
42 | } | ||
43 | |||
44 | template < | ||
45 | class Func, | ||
46 | typename = void_t< | ||
47 | decltype(std::declval<Func>()(std::declval<Arg>()...))>> | ||
48 | static constexpr bool value(char) | ||
49 | { | ||
50 | return false; | ||
51 | } | ||
52 | |||
53 | template < | ||
54 | class Func, | ||
55 | typename = void_t<decltype(std::declval<Func>()( | ||
56 | std::declval<Obj &>(), | ||
57 | std::declval<Arg>()...))>> | ||
58 | static constexpr bool value(int) | ||
59 | { | ||
60 | return true; | ||
61 | } | ||
62 | }; | ||
63 | |||
64 | template <class Func, class Obj, class... Args> | ||
65 | constexpr bool takes_obj_as_first_parameter() | ||
66 | { | ||
67 | return takes_obj_as_first_parameter_i<Obj, Args...>::template value<Func>( | ||
68 | 0); | ||
69 | } | ||
70 | |||
71 | template <bool with_obj, bool with_result> struct call_lambda | ||
72 | { | ||
73 | template <class Result, class Obj, class Func> static void | ||
74 | call(Func &&func, Obj &obj, QFutureWatcher<Result> const *watcher) | ||
75 | { | ||
76 | func(obj, watcher->result()); | ||
77 | } | ||
78 | }; | ||
79 | |||
80 | template <> struct call_lambda<false, true> | ||
81 | { | ||
82 | template <class Result, class Obj, class Func> static void | ||
83 | call(Func &&func, Obj &, QFutureWatcher<Result> const *watcher) | ||
84 | { | ||
85 | func(watcher->result()); | ||
86 | } | ||
87 | }; | ||
88 | template <> struct call_lambda<true, false> | ||
89 | { | ||
90 | template <class Result, class Obj, class Func> | ||
91 | static void call(Func &&func, Obj &obj, QFutureWatcher<Result> const *) | ||
92 | { | ||
93 | func(obj); | ||
94 | } | ||
95 | }; | ||
96 | |||
97 | template <> struct call_lambda<false, false> | ||
98 | { | ||
99 | template <class Result, class Obj, class Func> | ||
100 | static void call(Func &&func, Obj &, QFutureWatcher<Result> const *) | ||
101 | { | ||
102 | func(); | ||
103 | } | ||
104 | }; | ||
105 | |||
106 | template <class Result, class Obj> struct invoke | ||
107 | { | ||
108 | template <class Func> static void | ||
109 | call(Func &&func, Obj &obj, QFutureWatcher<Result> const *watcher) | ||
110 | { | ||
111 | call_lambda<takes_obj_as_first_parameter<Func, Obj, Result>(), true>:: | ||
112 | call(std::forward<Func>(func), obj, watcher); | ||
113 | } | ||
114 | |||
115 | template <class FnArg> static void | ||
116 | 15 | call(void (Obj::*member)(FnArg), | |
117 | Obj &obj, | ||
118 | QFutureWatcher<Result> const *watcher) | ||
119 | { | ||
120 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 11 times.
✓ Branch 16 taken 11 times.
✗ Branch 17 not taken.
|
15 | (obj.*member)(watcher->result()); |
121 | 15 | } | |
122 | }; | ||
123 | |||
124 | template <class Obj> struct invoke<void, Obj> | ||
125 | { | ||
126 | template <class Func> static void | ||
127 | call(Func &&func, Obj &obj, QFutureWatcher<void> const *watcher) | ||
128 | { | ||
129 | call_lambda<takes_obj_as_first_parameter<Func, Obj>(), false>::call( | ||
130 | std::forward<Func>(func), | ||
131 | obj, | ||
132 | watcher); | ||
133 | } | ||
134 | |||
135 | static void | ||
136 | call(void (Obj::*member)(), | ||
137 | Obj &obj, | ||
138 | QFutureWatcher<void> const * /* watcher */) | ||
139 | { | ||
140 | (obj.*member)(); | ||
141 | } | ||
142 | }; | ||
143 | |||
144 | }} // namespace QtPdCom::details | ||
145 | |||
146 | #endif // QTPDCOM_FUTUREWATCHERS_DETAILS_H | ||
147 |