GCC Code Coverage Report


Directory: ./
File: QtPdCom1/FutureWatchersDetails.h
Date: 2024-01-26 10:40:55
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