GCC Code Coverage Report


Directory: ./
File: include/pdcom5/Future.h
Date: 2024-02-26 09:07:35
Exec Total Coverage
Lines: 7 15 46.7%
Branches: 0 0 -%

Line Branch Exec Source
1 /*****************************************************************************
2 * vim:tw=78
3 *
4 * Copyright (C) 2022 Bjarne von Horn (vh at igh dot de).
5 *
6 * This file is part of the PdCom library.
7 *
8 * The PdCom library is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * The PdCom library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with the PdCom library. If not, see <http://www.gnu.org/licenses/>.
20 *
21 *****************************************************************************/
22
23 #ifndef PDCOM5_FUTURE_H
24 #define PDCOM5_FUTURE_H
25
26 #include <functional>
27 #include <memory>
28 #include <pdcom5_export.h>
29
30 namespace PdCom {
31 namespace impl {
32 template <class Exception, class... Result>
33 struct Promise;
34 }
35
36 /** Callback management handle.
37 *
38 * This class can save up to two callbacks for an asynchronous operation.
39 * When the result of the asynchronous operation arrives,
40 * the callback set by then() is called.
41 * On error, handle_exception() is invoked.
42 *
43 * Please note that this Future does not support fire-and-forget.
44 * The Future should be kept until one of the callback was called.
45 * If you're not interested in the result anymore, you can delete the future.
46 * In this case, no callbacks are run.
47 */
48 template <class Exception, class... Result>
49 25 class PDCOM5_PUBLIC Future
50 {
51 public:
52 using ResolveFn = std::function<void(Result...)>;
53 using RejectFn = std::function<void(Exception)>;
54
55 /// Default Constructor.
56 15 Future() = default;
57 2 Future(std::shared_ptr<impl::Promise<Exception, Result...>> impl) noexcept :
58 2 impl_(std::move(impl))
59 2 {}
60 8 Future(Future &&) = default;
61 Future(const Future &) = delete;
62 Future &operator=(Future &&) = default;
63 Future &operator=(const Future &) = delete;
64
65 /** Set continuation callback.
66 *
67 * \param resolve The callback to be invoked with the result.
68 * \return const Reference to \c this.
69 */
70 const Future &then(ResolveFn resolve) const &;
71 /** Set continuation callback.
72 *
73 * \param resolve The callback to be invoked with the result.
74 * \return a new Future.
75 */
76 Future then(ResolveFn resolve) &&;
77 /** Set error handling callback
78 *
79 * \param reject The callback to be invoked on error.
80 * \return const Reference to \c this.
81 */
82 const Future &handle_exception(RejectFn reject) const &;
83 /** Set error handling callback
84 *
85 * \param reject The callback to be invoked on error.
86 * \return a new Future.
87 */
88 Future handle_exception(RejectFn reject) &&;
89
90 /**
91 * \return true if the Future was default-constructed.
92 */
93 11 bool empty() const noexcept { return !impl_.operator bool(); }
94
95 /// Hash support, e.g. for \c std::unordered_set
96 struct Hash
97 {
98 std::size_t operator()(Future const &future) const
99 {
100 return std::hash<
101 std::shared_ptr<impl::Promise<Exception, Result...>>>()(
102 future.impl_);
103 }
104 };
105
106 /// Less compare support, e.g. for \c std::set
107 struct Less
108 {
109 bool operator()(const Future &lhs, const Future &rhs) const noexcept
110 {
111 return std::owner_less<
112 std::shared_ptr<impl::Promise<Exception, Result...>>>()(
113 lhs.impl_, rhs.impl_);
114 }
115 };
116
117 /// Equal comparsion.
118 bool operator==(const Future &other) const noexcept
119 {
120 return other.impl_ == impl_;
121 }
122
123 private:
124 std::shared_ptr<impl::Promise<Exception, Result...>> impl_;
125 };
126 } // namespace PdCom
127
128 namespace std {
129 template <class Exception, class... Result>
130 struct hash<PdCom::Future<Exception, Result...>> :
131 PdCom::Future<Exception, Result...>::Hash
132 {};
133
134 template <class Exception, class... Result>
135 struct less<PdCom::Future<Exception, Result...>> :
136 PdCom::Future<Exception, Result...>::Less
137 {};
138
139 } // namespace std
140
141
142 #endif // PDCOM5_FUTURE_H
143