| Directory: | ./ |
|---|---|
| File: | QtPdCom1/FutureWatchersDetails.h |
| Date: | 2025-11-14 14:56:08 |
| 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 |