Google Cloud C++ Client 2.10.1
C++ Client Library for Google Cloud Platform
Loading...
Searching...
No Matches
future_void.h
1// Copyright 2018 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_FUTURE_VOID_H
16#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_FUTURE_VOID_H
17/**
18 * @file
19 *
20 * Fully specialize `future<void>` and `promise<R>` for void.
21 */
22
23#include "google/cloud/internal/future_base.h"
24#include "google/cloud/internal/future_fwd.h"
25#include "google/cloud/internal/future_impl.h"
26#include "google/cloud/internal/future_then_meta.h"
27#include "google/cloud/version.h"
28
29namespace google {
30namespace cloud {
32/**
33 * Implement ISO/IEC TS 19571:2016 future for void.
34 */
35template <>
36class future<void> final : private internal::future_base<void> {
37 public:
38 using shared_state_type =
39 typename internal::future_base<void>::shared_state_type;
40
41 // workaround Apple Clang-7xx series bug, if we use `= default` here, the
42 // compiler believes there is no default constructor defined. :shrug:
43 future() noexcept {} // NOLINT(modernize-use-equals-default)
44
45 /**
46 * Creates a new future that unwraps @p rhs.
47 *
48 * This constructor creates a new shared state that becomes satisfied when
49 * both `rhs` and `rhs.get()` become satisfied. If `rhs` is satisfied, but
50 * `rhs.get()` returns an invalid future then the newly created future becomes
51 * satisfied with a `std::future_error` exception, and the exception error
52 * code is `std::future_errc::broken_promise`.
53 *
54 * @note The technical specification requires this to be a `noexcept`
55 * constructor I (coryan) believe this is a defect in the technical
56 * specification, as this *creates* a new shared state: shared states are
57 * dynamically allocated, and the allocator (which might be the default
58 * `operator new`) may raise.
59 */
60 // NOLINTNEXTLINE(google-explicit-constructor)
61 future(future<future<void>>&& rhs) noexcept(false);
62
63 /**
64 * Creates a future from a future whose result type is convertible to this
65 * future's result type.
66 */
67 template <class T>
68 explicit future(future<T>&& rhs) : future<void>(rhs.then([](future<T>) {})) {}
69
70 /**
71 * Waits until the shared state becomes ready, then retrieves the value stored
72 * in the shared state.
73 *
74 * @throws any exceptions stored in the shared state.
75 * @throws std::future_error with std::no_state if the future does not have
76 * a shared state.
77 */
78 void get() {
79 check_valid();
80 std::shared_ptr<shared_state_type> tmp;
81 tmp.swap(shared_state_);
82 return tmp->get();
83 }
84
85 using future_base::cancel;
86 using future_base::is_ready;
87 using future_base::valid;
88 using future_base::wait;
89 using future_base::wait_for;
90 using future_base::wait_until;
91
92 /**
93 * Attach a continuation to the future.
94 *
95 * Attach a callable @a func to be invoked when the future is
96 * ready. The return type is a future wrapping the return type of
97 * @a func.
98 *
99 * @return `future<T>` where T is `std::result_of_t<F, R>` (basically).
100 * If T matches `future<U>` then it returns `future<U>`. The returned
101 * future will contain the result of @a func.
102 * @param func a Callable to be invoked when the future is ready.
103 * The function might be called immediately, e.g., if the future is
104 * ready.
105 *
106 * Side effects: `valid() == false` if the operation is successful.
107 */
108 template <typename F>
109 typename internal::then_helper<F, void>::future_t then(F&& func) {
110 check_valid();
111 using requires_unwrap_t =
112 typename internal::then_helper<F, void>::requires_unwrap_t;
113 return then_impl(std::forward<F>(func), requires_unwrap_t{});
114 }
115
116 explicit future(std::shared_ptr<shared_state_type> state)
117 : future_base<void>(std::move(state)) {}
118
119 private:
120 /// Implement `then()` if the result does not require unwrapping.
121 template <typename F>
122 typename internal::then_helper<F, void>::future_t then_impl(F&& functor,
123 std::false_type);
124
125 /// Implement `then()` if the result requires unwrapping.
126 template <typename F>
127 typename internal::then_helper<F, void>::future_t then_impl(F&& functor,
128 std::true_type);
129
130 template <typename U>
131 friend class future;
132
133 friend struct internal::CoroutineSupport;
134};
135
136/**
137 * Specialize promise as defined in ISO/IEC TS 19571:2016 for void.
138 */
139template <>
140class promise<void> final : private internal::promise_base<void> {
141 public:
142 /// Creates a promise with an unsatisfied shared state.
143 promise() : promise_base([] {}) {}
144
145 /// Creates a promise with an unsatisfied shared state.
146 explicit promise(std::function<void()> cancellation_callback)
147 : promise_base(std::move(cancellation_callback)) {}
148
149 /// Creates a promise *without* a shared state.
150 explicit promise(null_promise_t x) : promise_base(std::move(x)) {}
151
152 /// Constructs a new promise and transfer any shared state from @p rhs.
153 promise(promise&&) = default;
154
155 /// Abandons the shared state in `*this`, if any, and transfers the shared
156 /// state from @p rhs.
157 promise& operator=(promise&& rhs) noexcept {
158 promise tmp(std::move(rhs));
159 tmp.swap(*this);
160 return *this;
161 }
162
163 /**
164 * Abandons any shared state.
165 *
166 * If the shared state was not already satisfied it becomes satisfied with
167 * a `std::future_error` exception. The error code in this exception is
168 * `std::future_errc::broken_promise`.
169 */
170 ~promise() = default;
171
172 promise(promise const&) = delete;
173 promise& operator=(promise const&) = delete;
174
175 /// Swaps the shared state in `*this` with @p rhs.
176 void swap(promise& other) noexcept {
177 std::swap(shared_state_, other.shared_state_);
178 }
179
180 /**
181 * Creates the `future<void>` using the same shared state as `*this`.
182 */
183 future<void> get_future() {
184 shared_state_type::mark_retrieved(shared_state_);
185 return future<void>(shared_state_);
186 }
187
188 /**
189 * Satisfies the shared state.
190 *
191 * @throws std::future_error with std::future_errc::promise_already_satisfied
192 * if the shared state is already satisfied.
193 * @throws std::future_error with std::no_state if the promise does not have
194 * a shared state.
195 */
196 void set_value() {
197 if (!shared_state_) {
198 internal::ThrowFutureError(std::future_errc::no_state, __func__);
199 }
200 shared_state_->set_value();
201 }
202
203 using promise_base<void>::set_exception;
204};
205
206/// Create a future<void> that is immediately ready.
207inline future<void> make_ready_future() {
208 promise<void> p;
210 return p.get_future();
211}
212
214} // namespace cloud
215} // namespace google
216
217#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_FUTURE_VOID_H
void get()
Waits until the shared state becomes ready, then retrieves the value stored in the shared state.
Definition: future_void.h:78
future() noexcept
Definition: future_void.h:43
future(future< T > &&rhs)
Creates a future from a future whose result type is convertible to this future's result type.
Definition: future_void.h:68
future(std::shared_ptr< shared_state_type > state)
Definition: future_void.h:116
internal::then_helper< F, void >::future_t then(F &&func)
Attach a continuation to the future.
Definition: future_void.h:109
future(future< future< void > > &&rhs) noexcept(false)
Creates a new future that unwraps rhs.
friend class future
Definition: future_generic.h:137
promise & operator=(promise const &)=delete
promise & operator=(promise &&rhs) noexcept
Abandons the shared state in *this, if any, and transfers the shared state from rhs.
Definition: future_void.h:157
promise(null_promise_t x)
Creates a promise without a shared state.
Definition: future_void.h:150
future< void > get_future()
Creates the future<void> using the same shared state as *this.
Definition: future_void.h:183
void swap(promise &other) noexcept
Swaps the shared state in *this with rhs.
Definition: future_void.h:176
void set_value()
Satisfies the shared state.
Definition: future_void.h:196
~promise()=default
Abandons any shared state.
promise(std::function< void()> cancellation_callback)
Creates a promise with an unsatisfied shared state.
Definition: future_void.h:146
promise()
Creates a promise with an unsatisfied shared state.
Definition: future_void.h:143
promise(promise &&)=default
Constructs a new promise and transfer any shared state from rhs.
promise(promise const &)=delete
Contains all the Google Cloud C++ Library APIs.
Definition: async_operation.h:23
future< void > make_ready_future()
Create a future<void> that is immediately ready.
Definition: future_void.h:207
Definition: async_operation.h:22
#define GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Definition: version.h:45
#define GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
Definition: version.h:43