]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/fiber/future/future.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / fiber / future / future.hpp
1
2 // Copyright Oliver Kowalke 2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef BOOST_FIBERS_FUTURE_HPP
8 #define BOOST_FIBERS_FUTURE_HPP
9
10 #include <algorithm>
11 #include <chrono>
12 #include <exception>
13
14 #include <boost/config.hpp>
15
16 #include <boost/fiber/detail/config.hpp>
17 #include <boost/fiber/exceptions.hpp>
18 #include <boost/fiber/future/detail/shared_state.hpp>
19 #include <boost/fiber/future/future_status.hpp>
20
21 namespace boost {
22 namespace fibers {
23 namespace detail {
24
25 template< typename R >
26 struct future_base {
27 typedef typename shared_state< R >::ptr_type ptr_type;
28
29 ptr_type state_{};
30
31 future_base() = default;
32
33 explicit future_base( ptr_type const& p) noexcept :
34 state_{ p } {
35 }
36
37 ~future_base() = default;
38
39 future_base( future_base const& other) :
40 state_{ other.state_ } {
41 }
42
43 future_base( future_base && other) noexcept :
44 state_{ other.state_ } {
45 other.state_.reset();
46 }
47
48 future_base & operator=( future_base const& other) noexcept {
49 if ( BOOST_LIKELY( this != & other) ) {
50 state_ = other.state_;
51 }
52 return * this;
53 }
54
55 future_base & operator=( future_base && other) noexcept {
56 if ( BOOST_LIKELY( this != & other) ) {
57 state_ = other.state_;
58 other.state_.reset();
59 }
60 return * this;
61 }
62
63 bool valid() const noexcept {
64 return nullptr != state_.get();
65 }
66
67 std::exception_ptr get_exception_ptr() {
68 if ( BOOST_UNLIKELY( ! valid() ) ) {
69 throw future_uninitialized{};
70 }
71 return state_->get_exception_ptr();
72 }
73
74 void wait() const {
75 if ( BOOST_UNLIKELY( ! valid() ) ) {
76 throw future_uninitialized{};
77 }
78 state_->wait();
79 }
80
81 template< typename Rep, typename Period >
82 future_status wait_for( std::chrono::duration< Rep, Period > const& timeout_duration) const {
83 if ( BOOST_UNLIKELY( ! valid() ) ) {
84 throw future_uninitialized{};
85 }
86 return state_->wait_for( timeout_duration);
87 }
88
89 template< typename Clock, typename Duration >
90 future_status wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time) const {
91 if ( BOOST_UNLIKELY( ! valid() ) ) {
92 throw future_uninitialized{};
93 }
94 return state_->wait_until( timeout_time);
95 }
96 };
97
98 template< typename R >
99 struct promise_base;
100
101 }
102
103 template< typename R >
104 class shared_future;
105
106 template< typename Signature >
107 class packaged_task;
108
109 template< typename R >
110 class future : private detail::future_base< R > {
111 private:
112 typedef detail::future_base< R > base_type;
113
114 friend struct detail::promise_base< R >;
115 friend class shared_future< R >;
116 template< typename Signature >
117 friend class packaged_task;
118
119 explicit future( typename base_type::ptr_type const& p) noexcept :
120 base_type{ p } {
121 }
122
123 public:
124 future() = default;
125
126 future( future const&) = delete;
127 future & operator=( future const&) = delete;
128
129 future( future && other) noexcept :
130 base_type{ std::move( other) } {
131 }
132
133 future & operator=( future && other) noexcept {
134 if ( BOOST_LIKELY( this != & other) ) {
135 base_type::operator=( std::move( other) );
136 }
137 return * this;
138 }
139
140 shared_future< R > share();
141
142 R get() {
143 if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
144 throw future_uninitialized{};
145 }
146 typename base_type::ptr_type tmp{};
147 tmp.swap( base_type::state_);
148 return std::move( tmp->get() );
149 }
150
151 using base_type::valid;
152 using base_type::get_exception_ptr;
153 using base_type::wait;
154 using base_type::wait_for;
155 using base_type::wait_until;
156 };
157
158 template< typename R >
159 class future< R & > : private detail::future_base< R & > {
160 private:
161 typedef detail::future_base< R & > base_type;
162
163 friend struct detail::promise_base< R & >;
164 friend class shared_future< R & >;
165 template< typename Signature >
166 friend class packaged_task;
167
168 explicit future( typename base_type::ptr_type const& p) noexcept :
169 base_type{ p } {
170 }
171
172 public:
173 future() = default;
174
175 future( future const&) = delete;
176 future & operator=( future const&) = delete;
177
178 future( future && other) noexcept :
179 base_type{ std::move( other) } {
180 }
181
182 future & operator=( future && other) noexcept {
183 if ( BOOST_LIKELY( this != & other) ) {
184 base_type::operator=( std::move( other) );
185 }
186 return * this;
187 }
188
189 shared_future< R & > share();
190
191 R & get() {
192 if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
193 throw future_uninitialized{};
194 }
195 typename base_type::ptr_type tmp{};
196 tmp.swap( base_type::state_);
197 return tmp->get();
198 }
199
200 using base_type::valid;
201 using base_type::get_exception_ptr;
202 using base_type::wait;
203 using base_type::wait_for;
204 using base_type::wait_until;
205 };
206
207 template<>
208 class future< void > : private detail::future_base< void > {
209 private:
210 typedef detail::future_base< void > base_type;
211
212 friend struct detail::promise_base< void >;
213 friend class shared_future< void >;
214 template< typename Signature >
215 friend class packaged_task;
216
217 explicit future( base_type::ptr_type const& p) noexcept :
218 base_type{ p } {
219 }
220
221 public:
222 future() = default;
223
224 future( future const&) = delete;
225 future & operator=( future const&) = delete;
226
227 inline
228 future( future && other) noexcept :
229 base_type{ std::move( other) } {
230 }
231
232 inline
233 future & operator=( future && other) noexcept {
234 if ( BOOST_LIKELY( this != & other) ) {
235 base_type::operator=( std::move( other) );
236 }
237 return * this;
238 }
239
240 shared_future< void > share();
241
242 inline
243 void get() {
244 if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
245 throw future_uninitialized{};
246 }
247 base_type::ptr_type tmp{};
248 tmp.swap( base_type::state_);
249 tmp->get();
250 }
251
252 using base_type::valid;
253 using base_type::get_exception_ptr;
254 using base_type::wait;
255 using base_type::wait_for;
256 using base_type::wait_until;
257 };
258
259
260 template< typename R >
261 class shared_future : private detail::future_base< R > {
262 private:
263 typedef detail::future_base< R > base_type;
264
265 explicit shared_future( typename base_type::ptr_type const& p) noexcept :
266 base_type{ p } {
267 }
268
269 public:
270 shared_future() = default;
271
272 ~shared_future() = default;
273
274 shared_future( shared_future const& other) :
275 base_type{ other } {
276 }
277
278 shared_future( shared_future && other) noexcept :
279 base_type{ std::move( other) } {
280 }
281
282 shared_future( future< R > && other) noexcept :
283 base_type{ std::move( other) } {
284 }
285
286 shared_future & operator=( shared_future const& other) noexcept {
287 if ( BOOST_LIKELY( this != & other) ) {
288 base_type::operator=( other);
289 }
290 return * this;
291 }
292
293 shared_future & operator=( shared_future && other) noexcept {
294 if ( BOOST_LIKELY( this != & other) ) {
295 base_type::operator=( std::move( other) );
296 }
297 return * this;
298 }
299
300 shared_future & operator=( future< R > && other) noexcept {
301 base_type::operator=( std::move( other) );
302 return * this;
303 }
304
305 R const& get() const {
306 if ( BOOST_UNLIKELY( ! valid() ) ) {
307 throw future_uninitialized{};
308 }
309 return base_type::state_->get();
310 }
311
312 using base_type::valid;
313 using base_type::get_exception_ptr;
314 using base_type::wait;
315 using base_type::wait_for;
316 using base_type::wait_until;
317 };
318
319 template< typename R >
320 class shared_future< R & > : private detail::future_base< R & > {
321 private:
322 typedef detail::future_base< R & > base_type;
323
324 explicit shared_future( typename base_type::ptr_type const& p) noexcept :
325 base_type{ p } {
326 }
327
328 public:
329 shared_future() = default;
330
331 ~shared_future() = default;
332
333 shared_future( shared_future const& other) :
334 base_type{ other } {
335 }
336
337 shared_future( shared_future && other) noexcept :
338 base_type{ std::move( other) } {
339 }
340
341 shared_future( future< R & > && other) noexcept :
342 base_type{ std::move( other) } {
343 }
344
345 shared_future & operator=( shared_future const& other) noexcept {
346 if ( BOOST_LIKELY( this != & other) ) {
347 base_type::operator=( other);
348 }
349 return * this;
350 }
351
352 shared_future & operator=( shared_future && other) noexcept {
353 if ( BOOST_LIKELY( this != & other) ) {
354 base_type::operator=( std::move( other) );
355 }
356 return * this;
357 }
358
359 shared_future & operator=( future< R & > && other) noexcept {
360 base_type::operator=( std::move( other) );
361 return * this;
362 }
363
364 R & get() const {
365 if ( BOOST_UNLIKELY( ! valid() ) ) {
366 throw future_uninitialized{};
367 }
368 return base_type::state_->get();
369 }
370
371 using base_type::valid;
372 using base_type::get_exception_ptr;
373 using base_type::wait;
374 using base_type::wait_for;
375 using base_type::wait_until;
376 };
377
378 template<>
379 class shared_future< void > : private detail::future_base< void > {
380 private:
381 typedef detail::future_base< void > base_type;
382
383 explicit shared_future( base_type::ptr_type const& p) noexcept :
384 base_type{ p } {
385 }
386
387 public:
388 shared_future() = default;
389
390 ~shared_future() = default;
391
392 inline
393 shared_future( shared_future const& other) :
394 base_type{ other } {
395 }
396
397 inline
398 shared_future( shared_future && other) noexcept :
399 base_type{ std::move( other) } {
400 }
401
402 inline
403 shared_future( future< void > && other) noexcept :
404 base_type{ std::move( other) } {
405 }
406
407 inline
408 shared_future & operator=( shared_future const& other) noexcept {
409 if ( BOOST_LIKELY( this != & other) ) {
410 base_type::operator=( other);
411 }
412 return * this;
413 }
414
415 inline
416 shared_future & operator=( shared_future && other) noexcept {
417 if ( BOOST_LIKELY( this != & other) ) {
418 base_type::operator=( std::move( other) );
419 }
420 return * this;
421 }
422
423 inline
424 shared_future & operator=( future< void > && other) noexcept {
425 base_type::operator=( std::move( other) );
426 return * this;
427 }
428
429 inline
430 void get() const {
431 if ( BOOST_UNLIKELY( ! valid() ) ) {
432 throw future_uninitialized{};
433 }
434 base_type::state_->get();
435 }
436
437 using base_type::valid;
438 using base_type::get_exception_ptr;
439 using base_type::wait;
440 using base_type::wait_for;
441 using base_type::wait_until;
442 };
443
444
445 template< typename R >
446 shared_future< R >
447 future< R >::share() {
448 if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
449 throw future_uninitialized{};
450 }
451 return shared_future< R >{ std::move( * this) };
452 }
453
454 template< typename R >
455 shared_future< R & >
456 future< R & >::share() {
457 if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
458 throw future_uninitialized{};
459 }
460 return shared_future< R & >{ std::move( * this) };
461 }
462
463 inline
464 shared_future< void >
465 future< void >::share() {
466 if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
467 throw future_uninitialized{};
468 }
469 return shared_future< void >{ std::move( * this) };
470 }
471
472 }}
473
474 #endif