blob: 5d2732b73cf61c7a958e3a43144bb0aed68adfeb [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUTURE
11#define _LIBCPP_FUTURE
12
13/*
14 future synopsis
15
16namespace std
17{
18
19enum class future_errc
20{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000021 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000022 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000023 no_state,
24 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000025};
26
27enum class launch
28{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000029 async = 1,
30 deferred = 2,
31 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000032};
33
34enum class future_status
35{
36 ready,
37 timeout,
38 deferred
39};
40
41template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000042error_code make_error_code(future_errc e) noexcept;
43error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000044
Howard Hinnant22448042012-07-21 17:46:55 +000045const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000046
47class future_error
48 : public logic_error
49{
50public:
51 future_error(error_code ec); // exposition only
Marshall Clowd4a669c2016-11-14 18:56:24 +000052 explicit future_error(future_errc); // C++17
Howard Hinnant22448042012-07-21 17:46:55 +000053 const error_code& code() const noexcept;
54 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000055};
56
57template <class R>
58class promise
59{
60public:
61 promise();
62 template <class Allocator>
63 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000064 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000065 promise(const promise& rhs) = delete;
66 ~promise();
67
68 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000069 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000070 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000071 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000072
73 // retrieving the result
74 future<R> get_future();
75
76 // setting the result
77 void set_value(const R& r);
78 void set_value(R&& r);
79 void set_exception(exception_ptr p);
80
81 // setting the result with deferred notification
82 void set_value_at_thread_exit(const R& r);
83 void set_value_at_thread_exit(R&& r);
84 void set_exception_at_thread_exit(exception_ptr p);
85};
86
87template <class R>
88class promise<R&>
89{
90public:
91 promise();
92 template <class Allocator>
93 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000094 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000095 promise(const promise& rhs) = delete;
96 ~promise();
97
98 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000099 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000100 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000101 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000102
103 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000104 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000105
106 // setting the result
107 void set_value(R& r);
108 void set_exception(exception_ptr p);
109
110 // setting the result with deferred notification
111 void set_value_at_thread_exit(R&);
112 void set_exception_at_thread_exit(exception_ptr p);
113};
114
115template <>
116class promise<void>
117{
118public:
119 promise();
120 template <class Allocator>
121 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000122 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000123 promise(const promise& rhs) = delete;
124 ~promise();
125
126 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000127 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000128 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000129 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000130
131 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000132 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000133
134 // setting the result
135 void set_value();
136 void set_exception(exception_ptr p);
137
138 // setting the result with deferred notification
139 void set_value_at_thread_exit();
140 void set_exception_at_thread_exit(exception_ptr p);
141};
142
Howard Hinnant22448042012-07-21 17:46:55 +0000143template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000144
145template <class R, class Alloc>
146 struct uses_allocator<promise<R>, Alloc> : public true_type {};
147
148template <class R>
149class future
150{
151public:
Howard Hinnant22448042012-07-21 17:46:55 +0000152 future() noexcept;
153 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000154 future(const future& rhs) = delete;
155 ~future();
156 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000157 future& operator=(future&&) noexcept;
Marshall Clow597881d2017-01-25 20:14:03 +0000158 shared_future<R> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000159
160 // retrieving the value
161 R get();
162
163 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000164 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000165
166 void wait() const;
167 template <class Rep, class Period>
168 future_status
169 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
170 template <class Clock, class Duration>
171 future_status
172 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
173};
174
175template <class R>
176class future<R&>
177{
178public:
Howard Hinnant22448042012-07-21 17:46:55 +0000179 future() noexcept;
180 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000181 future(const future& rhs) = delete;
182 ~future();
183 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000184 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000185 shared_future<R&> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000186
187 // retrieving the value
188 R& get();
189
190 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000191 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000192
193 void wait() const;
194 template <class Rep, class Period>
195 future_status
196 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
197 template <class Clock, class Duration>
198 future_status
199 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
200};
201
202template <>
203class future<void>
204{
205public:
Howard Hinnant22448042012-07-21 17:46:55 +0000206 future() noexcept;
207 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000208 future(const future& rhs) = delete;
209 ~future();
210 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000211 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000212 shared_future<void> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000213
214 // retrieving the value
215 void get();
216
217 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000218 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000219
220 void wait() const;
221 template <class Rep, class Period>
222 future_status
223 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
224 template <class Clock, class Duration>
225 future_status
226 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
227};
228
229template <class R>
230class shared_future
231{
232public:
Howard Hinnant22448042012-07-21 17:46:55 +0000233 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000234 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000235 shared_future(future<R>&&) noexcept;
236 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000237 ~shared_future();
238 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000239 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000240
241 // retrieving the value
242 const R& get() const;
243
244 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000245 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246
247 void wait() const;
248 template <class Rep, class Period>
249 future_status
250 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
251 template <class Clock, class Duration>
252 future_status
253 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
254};
255
256template <class R>
257class shared_future<R&>
258{
259public:
Howard Hinnant22448042012-07-21 17:46:55 +0000260 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000261 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000262 shared_future(future<R&>&&) noexcept;
263 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264 ~shared_future();
265 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000266 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000267
268 // retrieving the value
269 R& get() const;
270
271 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000272 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000273
274 void wait() const;
275 template <class Rep, class Period>
276 future_status
277 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
278 template <class Clock, class Duration>
279 future_status
280 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
281};
282
283template <>
284class shared_future<void>
285{
286public:
Howard Hinnant22448042012-07-21 17:46:55 +0000287 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000288 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000289 shared_future(future<void>&&) noexcept;
290 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000291 ~shared_future();
292 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000293 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000294
295 // retrieving the value
296 void get() const;
297
298 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000299 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000300
301 void wait() const;
302 template <class Rep, class Period>
303 future_status
304 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
305 template <class Clock, class Duration>
306 future_status
307 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
308};
309
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000311 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000312 async(F&& f, Args&&... args);
313
314template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000315 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000316 async(launch policy, F&& f, Args&&... args);
317
Howard Hinnantc566dc32010-05-11 21:36:01 +0000318template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000319
320template <class R, class... ArgTypes>
321class packaged_task<R(ArgTypes...)>
322{
323public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +0000324 typedef R result_type; // extension
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325
326 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000327 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000328 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 explicit packaged_task(F&& f);
Marshall Clowa0a057e2017-11-27 20:47:54 +0000330 template <class F, class Allocator>
331 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332 ~packaged_task();
333
334 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000335 packaged_task(const packaged_task&) = delete;
336 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337
338 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000339 packaged_task(packaged_task&& other) noexcept;
340 packaged_task& operator=(packaged_task&& other) noexcept;
341 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000342
Howard Hinnant22448042012-07-21 17:46:55 +0000343 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344
345 // result retrieval
346 future<R> get_future();
347
348 // execution
349 void operator()(ArgTypes... );
350 void make_ready_at_thread_exit(ArgTypes...);
351
352 void reset();
353};
354
355template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000356 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000357
Marshall Clowa0a057e2017-11-27 20:47:54 +0000358template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
359
Howard Hinnantc51e1022010-05-11 19:42:16 +0000360} // std
361
362*/
363
Louis Dionne73912b22020-11-04 15:01:25 -0500364#include <__availability>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400365#include <__config>
Arthur O'Dwyer597cac42021-05-12 23:04:03 -0400366#include <__debug>
Christopher Di Bella41f26e82021-06-05 02:47:47 +0000367#include <__utility/__decay_copy.h>
368#include <__utility/forward.h>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000369#include <chrono>
370#include <exception>
Arthur O'Dwyer597cac42021-05-12 23:04:03 -0400371#include <memory>
Howard Hinnante6a10852010-09-03 21:46:37 +0000372#include <mutex>
Arthur O'Dwyer597cac42021-05-12 23:04:03 -0400373#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000374#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000375
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000376#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000377#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000378#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000379
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000380#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000381#error <future> is not supported on this single threaded system
382#else // !_LIBCPP_HAS_NO_THREADS
383
Howard Hinnantc51e1022010-05-11 19:42:16 +0000384_LIBCPP_BEGIN_NAMESPACE_STD
385
386//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000387_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000388{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000389 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000391 no_state,
392 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000393};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000394_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000395
Howard Hinnant684902d2010-09-22 14:16:26 +0000396template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000397struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000398
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000399#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
400template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000401struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000402#endif
403
Howard Hinnantc51e1022010-05-11 19:42:16 +0000404//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000405_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000406{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000407 async = 1,
408 deferred = 2,
409 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000410};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000411_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000412
Howard Hinnantda760a82013-06-29 18:38:17 +0000413#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
414
Howard Hinnantda760a82013-06-29 18:38:17 +0000415typedef underlying_type<launch>::type __launch_underlying_type;
Howard Hinnantda760a82013-06-29 18:38:17 +0000416
417inline _LIBCPP_INLINE_VISIBILITY
418_LIBCPP_CONSTEXPR
419launch
420operator&(launch __x, launch __y)
421{
422 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
423 static_cast<__launch_underlying_type>(__y));
424}
425
426inline _LIBCPP_INLINE_VISIBILITY
427_LIBCPP_CONSTEXPR
428launch
429operator|(launch __x, launch __y)
430{
431 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
432 static_cast<__launch_underlying_type>(__y));
433}
434
435inline _LIBCPP_INLINE_VISIBILITY
436_LIBCPP_CONSTEXPR
437launch
438operator^(launch __x, launch __y)
439{
440 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
441 static_cast<__launch_underlying_type>(__y));
442}
443
444inline _LIBCPP_INLINE_VISIBILITY
445_LIBCPP_CONSTEXPR
446launch
447operator~(launch __x)
448{
Howard Hinnant373d7602013-07-02 18:01:41 +0000449 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000450}
451
452inline _LIBCPP_INLINE_VISIBILITY
453launch&
454operator&=(launch& __x, launch __y)
455{
456 __x = __x & __y; return __x;
457}
458
459inline _LIBCPP_INLINE_VISIBILITY
460launch&
461operator|=(launch& __x, launch __y)
462{
463 __x = __x | __y; return __x;
464}
465
466inline _LIBCPP_INLINE_VISIBILITY
467launch&
468operator^=(launch& __x, launch __y)
469{
470 __x = __x ^ __y; return __x;
471}
472
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400473#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
Howard Hinnantda760a82013-06-29 18:38:17 +0000474
Howard Hinnantc51e1022010-05-11 19:42:16 +0000475//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000476_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000477{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000478 ready,
479 timeout,
480 deferred
481};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000482_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000483
Howard Hinnant8331b762013-03-06 23:30:19 +0000484_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000485const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000486
487inline _LIBCPP_INLINE_VISIBILITY
488error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000489make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000490{
491 return error_code(static_cast<int>(__e), future_category());
492}
493
494inline _LIBCPP_INLINE_VISIBILITY
495error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000496make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000497{
498 return error_condition(static_cast<int>(__e), future_category());
499}
500
Mehdi Amini228053d2017-05-04 17:08:54 +0000501class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000502 : public logic_error
503{
504 error_code __ec_;
505public:
506 future_error(error_code __ec);
Marek Kurdejf3197922021-04-01 08:29:55 +0200507
Howard Hinnant684902d2010-09-22 14:16:26 +0000508 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000509 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000510
Dimitry Andric47269ce2020-03-13 19:36:26 +0100511 future_error(const future_error&) _NOEXCEPT = default;
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000512 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000513};
514
Louis Dionne16fe2952018-07-11 23:14:33 +0000515_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000516#ifndef _LIBCPP_NO_EXCEPTIONS
517_LIBCPP_AVAILABILITY_FUTURE_ERROR
518#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000519void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000520{
521#ifndef _LIBCPP_NO_EXCEPTIONS
522 throw future_error(make_error_code(_Ev));
523#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000524 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000525 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000526#endif
527}
528
Mehdi Amini228053d2017-05-04 17:08:54 +0000529class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000530 : public __shared_count
531{
532protected:
533 exception_ptr __exception_;
534 mutable mutex __mut_;
535 mutable condition_variable __cv_;
536 unsigned __state_;
537
Howard Hinnant719bda32011-05-28 14:41:13 +0000538 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000539 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000540public:
541 enum
542 {
543 __constructed = 1,
544 __future_attached = 2,
545 ready = 4,
546 deferred = 8
547 };
548
Howard Hinnant684902d2010-09-22 14:16:26 +0000549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000550 __assoc_sub_state() : __state_(0) {}
551
Howard Hinnant684902d2010-09-22 14:16:26 +0000552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000553 bool __has_value() const
554 {return (__state_ & __constructed) || (__exception_ != nullptr);}
555
Howard Hinnant684902d2010-09-22 14:16:26 +0000556 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000557 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000558 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000559 bool __has_future_attached = (__state_ & __future_attached) != 0;
560 if (__has_future_attached)
561 __throw_future_error(future_errc::future_already_retrieved);
562 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000563 __state_ |= __future_attached;
564 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000565
Howard Hinnant684902d2010-09-22 14:16:26 +0000566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000567 void __set_deferred() {__state_ |= deferred;}
568
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000569 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000570 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000571 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000572
573 void set_value();
574 void set_value_at_thread_exit();
575
576 void set_exception(exception_ptr __p);
577 void set_exception_at_thread_exit(exception_ptr __p);
578
579 void copy();
580
Howard Hinnantccdd2032010-08-30 18:46:21 +0000581 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000582 template <class _Rep, class _Period>
583 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000585 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
586 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000587 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000588 future_status
589 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000590
591 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000592};
593
Howard Hinnantf4712b92010-08-28 21:01:06 +0000594template <class _Clock, class _Duration>
595future_status
596__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
597{
598 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000599 if (__state_ & deferred)
600 return future_status::deferred;
601 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000602 __cv_.wait_until(__lk, __abs_time);
603 if (__state_ & ready)
604 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000605 return future_status::timeout;
606}
607
608template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000609inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000610future_status
611__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
612{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000613 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000614}
615
Howard Hinnantc834c512011-11-29 18:15:50 +0000616template <class _Rp>
Louis Dionne3b967d02019-12-10 18:00:42 -0500617class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000618 : public __assoc_sub_state
619{
620 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000621 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000622protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000623 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000624
Howard Hinnant719bda32011-05-28 14:41:13 +0000625 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000626public:
627
628 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400629 void set_value(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000630
631 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400632 void set_value_at_thread_exit(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000633
Howard Hinnantc834c512011-11-29 18:15:50 +0000634 _Rp move();
635 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000636};
637
Howard Hinnantc834c512011-11-29 18:15:50 +0000638template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000639void
Howard Hinnantc834c512011-11-29 18:15:50 +0000640__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000641{
642 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000643 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000644 delete this;
645}
646
Howard Hinnantc834c512011-11-29 18:15:50 +0000647template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000648template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000649_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000650void
Howard Hinnantc834c512011-11-29 18:15:50 +0000651__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000652{
653 unique_lock<mutex> __lk(this->__mut_);
654 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000655 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500656 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000657 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000658 __cv_.notify_all();
659}
660
Howard Hinnantc834c512011-11-29 18:15:50 +0000661template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000662template <class _Arg>
663void
Howard Hinnantc834c512011-11-29 18:15:50 +0000664__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000665{
666 unique_lock<mutex> __lk(this->__mut_);
667 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000668 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500669 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000670 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000671 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000672}
673
Howard Hinnantc834c512011-11-29 18:15:50 +0000674template <class _Rp>
675_Rp
676__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000677{
678 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000679 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000680 if (this->__exception_ != nullptr)
681 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000682 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000683}
684
Howard Hinnantc834c512011-11-29 18:15:50 +0000685template <class _Rp>
686typename add_lvalue_reference<_Rp>::type
687__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000688{
689 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000690 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000691 if (this->__exception_ != nullptr)
692 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000693 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000694}
695
Howard Hinnantc834c512011-11-29 18:15:50 +0000696template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000697class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000698 : public __assoc_sub_state
699{
700 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000701 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000702protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000703 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000704
Howard Hinnant719bda32011-05-28 14:41:13 +0000705 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000706public:
707
Howard Hinnantc834c512011-11-29 18:15:50 +0000708 void set_value(_Rp& __arg);
709 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000710
Howard Hinnantc834c512011-11-29 18:15:50 +0000711 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000712};
713
Howard Hinnantc834c512011-11-29 18:15:50 +0000714template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715void
Howard Hinnantc834c512011-11-29 18:15:50 +0000716__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000717{
718 delete this;
719}
720
Howard Hinnantc834c512011-11-29 18:15:50 +0000721template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000722void
Howard Hinnantc834c512011-11-29 18:15:50 +0000723__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000724{
725 unique_lock<mutex> __lk(this->__mut_);
726 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000727 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000728 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000729 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000730 __cv_.notify_all();
731}
732
Howard Hinnantc834c512011-11-29 18:15:50 +0000733template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000734void
Howard Hinnantc834c512011-11-29 18:15:50 +0000735__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000736{
737 unique_lock<mutex> __lk(this->__mut_);
738 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000739 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000740 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000741 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000742 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743}
744
Howard Hinnantc834c512011-11-29 18:15:50 +0000745template <class _Rp>
746_Rp&
747__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000748{
749 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000750 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000751 if (this->__exception_ != nullptr)
752 rethrow_exception(this->__exception_);
753 return *__value_;
754}
755
Howard Hinnantc834c512011-11-29 18:15:50 +0000756template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000757class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000758 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000759{
Howard Hinnantc834c512011-11-29 18:15:50 +0000760 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000761 _Alloc __alloc_;
762
Howard Hinnant719bda32011-05-28 14:41:13 +0000763 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000764public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000766 explicit __assoc_state_alloc(const _Alloc& __a)
767 : __alloc_(__a) {}
768};
769
Howard Hinnantc834c512011-11-29 18:15:50 +0000770template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000771void
Howard Hinnantc834c512011-11-29 18:15:50 +0000772__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000773{
774 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000775 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000776 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
777 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000778 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000779 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000780 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000781 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000782}
783
Howard Hinnantc834c512011-11-29 18:15:50 +0000784template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000785class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000786 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000787{
Howard Hinnantc834c512011-11-29 18:15:50 +0000788 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000789 _Alloc __alloc_;
790
Howard Hinnant719bda32011-05-28 14:41:13 +0000791 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000792public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000793 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000794 explicit __assoc_state_alloc(const _Alloc& __a)
795 : __alloc_(__a) {}
796};
797
Howard Hinnantc834c512011-11-29 18:15:50 +0000798template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000799void
Howard Hinnantc834c512011-11-29 18:15:50 +0000800__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000801{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000802 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
803 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000804 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000805 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000806 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000807 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000808}
809
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000810template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000811class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000812 : public __assoc_sub_state
813{
814 typedef __assoc_sub_state base;
815 _Alloc __alloc_;
816
Howard Hinnant719bda32011-05-28 14:41:13 +0000817 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000818public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000819 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000820 explicit __assoc_sub_state_alloc(const _Alloc& __a)
821 : __alloc_(__a) {}
822};
823
824template <class _Alloc>
825void
Howard Hinnant719bda32011-05-28 14:41:13 +0000826__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000827{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000828 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
829 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000830 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000831 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000832 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000833 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000834}
835
Howard Hinnantc834c512011-11-29 18:15:50 +0000836template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000837class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000838 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000839{
Howard Hinnantc834c512011-11-29 18:15:50 +0000840 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000841
Howard Hinnantc834c512011-11-29 18:15:50 +0000842 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000843
844public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000845 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000846 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000847
848 virtual void __execute();
849};
850
Howard Hinnantc834c512011-11-29 18:15:50 +0000851template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000852inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000853__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
854 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000855{
856 this->__set_deferred();
857}
858
Howard Hinnantc834c512011-11-29 18:15:50 +0000859template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000860void
Howard Hinnantc834c512011-11-29 18:15:50 +0000861__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000862{
863#ifndef _LIBCPP_NO_EXCEPTIONS
864 try
865 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400866#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000867 this->set_value(__func_());
868#ifndef _LIBCPP_NO_EXCEPTIONS
869 }
870 catch (...)
871 {
872 this->set_exception(current_exception());
873 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400874#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000875}
876
Howard Hinnantc834c512011-11-29 18:15:50 +0000877template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000878class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000879 : public __assoc_sub_state
880{
881 typedef __assoc_sub_state base;
882
Howard Hinnantc834c512011-11-29 18:15:50 +0000883 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000884
885public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000886 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000887 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000888
889 virtual void __execute();
890};
891
Howard Hinnantc834c512011-11-29 18:15:50 +0000892template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000893inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000894__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
895 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000896{
897 this->__set_deferred();
898}
899
Howard Hinnantc834c512011-11-29 18:15:50 +0000900template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000901void
Howard Hinnantc834c512011-11-29 18:15:50 +0000902__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000903{
904#ifndef _LIBCPP_NO_EXCEPTIONS
905 try
906 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400907#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000908 __func_();
909 this->set_value();
910#ifndef _LIBCPP_NO_EXCEPTIONS
911 }
912 catch (...)
913 {
914 this->set_exception(current_exception());
915 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400916#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000917}
918
Howard Hinnantc834c512011-11-29 18:15:50 +0000919template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000920class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000921 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000922{
Howard Hinnantc834c512011-11-29 18:15:50 +0000923 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000924
Howard Hinnantc834c512011-11-29 18:15:50 +0000925 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000926
Howard Hinnant719bda32011-05-28 14:41:13 +0000927 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000928public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000929 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000930 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000931
932 virtual void __execute();
933};
934
Howard Hinnantc834c512011-11-29 18:15:50 +0000935template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000936inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000937__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
938 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000939{
940}
941
Howard Hinnantc834c512011-11-29 18:15:50 +0000942template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000943void
Howard Hinnantc834c512011-11-29 18:15:50 +0000944__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000945{
946#ifndef _LIBCPP_NO_EXCEPTIONS
947 try
948 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400949#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +0000950 this->set_value(__func_());
951#ifndef _LIBCPP_NO_EXCEPTIONS
952 }
953 catch (...)
954 {
955 this->set_exception(current_exception());
956 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400957#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +0000958}
959
Howard Hinnantc834c512011-11-29 18:15:50 +0000960template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000961void
Howard Hinnantc834c512011-11-29 18:15:50 +0000962__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000963{
964 this->wait();
965 base::__on_zero_shared();
966}
967
Howard Hinnantc834c512011-11-29 18:15:50 +0000968template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000969class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000970 : public __assoc_sub_state
971{
972 typedef __assoc_sub_state base;
973
Howard Hinnantc834c512011-11-29 18:15:50 +0000974 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000975
Howard Hinnant719bda32011-05-28 14:41:13 +0000976 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000977public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000978 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000979 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000980
981 virtual void __execute();
982};
983
Howard Hinnantc834c512011-11-29 18:15:50 +0000984template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000985inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000986__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
987 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000988{
989}
990
Howard Hinnantc834c512011-11-29 18:15:50 +0000991template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000992void
Howard Hinnantc834c512011-11-29 18:15:50 +0000993__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000994{
995#ifndef _LIBCPP_NO_EXCEPTIONS
996 try
997 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400998#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +0000999 __func_();
1000 this->set_value();
1001#ifndef _LIBCPP_NO_EXCEPTIONS
1002 }
1003 catch (...)
1004 {
1005 this->set_exception(current_exception());
1006 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001007#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +00001008}
1009
Howard Hinnantc834c512011-11-29 18:15:50 +00001010template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001011void
Howard Hinnantc834c512011-11-29 18:15:50 +00001012__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001013{
1014 this->wait();
1015 base::__on_zero_shared();
1016}
1017
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001018template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1019template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001020
1021// future
1022
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001023template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001024
Howard Hinnantc834c512011-11-29 18:15:50 +00001025template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001026_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001027__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001028
Howard Hinnantc834c512011-11-29 18:15:50 +00001029template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001030_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001031__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001032
Howard Hinnantc834c512011-11-29 18:15:50 +00001033template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001034class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001035{
Howard Hinnantc834c512011-11-29 18:15:50 +00001036 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001037
Howard Hinnantc834c512011-11-29 18:15:50 +00001038 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001039
1040 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001041 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001042
Howard Hinnantc834c512011-11-29 18:15:50 +00001043 template <class _R1, class _Fp>
1044 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1045 template <class _R1, class _Fp>
1046 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001047
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001048public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001049 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001050 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001052 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001053 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1054 future(const future&) = delete;
1055 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001057 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001058 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001059 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001060 return *this;
1061 }
Louis Dionne7b844362020-07-30 09:42:23 -04001062
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001063 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001064 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001065 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001066
1067 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001068 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001069
Howard Hinnant684902d2010-09-22 14:16:26 +00001070 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001071 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001072
1073 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001074 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001075 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001076
Howard Hinnant684902d2010-09-22 14:16:26 +00001077 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001078 void wait() const {__state_->wait();}
1079 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001080 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001081 future_status
1082 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1083 {return __state_->wait_for(__rel_time);}
1084 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001085 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001086 future_status
1087 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1088 {return __state_->wait_until(__abs_time);}
1089};
1090
Howard Hinnantc834c512011-11-29 18:15:50 +00001091template <class _Rp>
1092future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001093 : __state_(__state)
1094{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001095 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001096}
1097
Howard Hinnantccdd2032010-08-30 18:46:21 +00001098struct __release_shared_count
1099{
1100 void operator()(__shared_count* p) {p->__release_shared();}
1101};
1102
Howard Hinnantc834c512011-11-29 18:15:50 +00001103template <class _Rp>
1104future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001105{
1106 if (__state_)
1107 __state_->__release_shared();
1108}
1109
Howard Hinnantc834c512011-11-29 18:15:50 +00001110template <class _Rp>
1111_Rp
1112future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001113{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001114 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001115 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001116 __state_ = nullptr;
1117 return __s->move();
1118}
1119
Howard Hinnantc834c512011-11-29 18:15:50 +00001120template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001121class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001122{
Howard Hinnantc834c512011-11-29 18:15:50 +00001123 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001124
Howard Hinnantc834c512011-11-29 18:15:50 +00001125 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001126
1127 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001128 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001129
Howard Hinnantc834c512011-11-29 18:15:50 +00001130 template <class _R1, class _Fp>
1131 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1132 template <class _R1, class _Fp>
1133 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001134
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001135public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001137 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001138 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001139 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001140 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1141 future(const future&) = delete;
1142 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001143 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001144 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001145 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001146 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001147 return *this;
1148 }
Louis Dionne7b844362020-07-30 09:42:23 -04001149
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001150 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001151 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001152 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001153
1154 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001155 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001156
Howard Hinnant684902d2010-09-22 14:16:26 +00001157 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001158 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001159
1160 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001161 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001162 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001163
Howard Hinnant684902d2010-09-22 14:16:26 +00001164 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001165 void wait() const {__state_->wait();}
1166 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001167 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001168 future_status
1169 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1170 {return __state_->wait_for(__rel_time);}
1171 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001172 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001173 future_status
1174 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1175 {return __state_->wait_until(__abs_time);}
1176};
1177
Howard Hinnantc834c512011-11-29 18:15:50 +00001178template <class _Rp>
1179future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001180 : __state_(__state)
1181{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001182 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001183}
1184
Howard Hinnantc834c512011-11-29 18:15:50 +00001185template <class _Rp>
1186future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001187{
1188 if (__state_)
1189 __state_->__release_shared();
1190}
1191
Howard Hinnantc834c512011-11-29 18:15:50 +00001192template <class _Rp>
1193_Rp&
1194future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001195{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001196 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001197 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001198 __state_ = nullptr;
1199 return __s->copy();
1200}
1201
1202template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001203class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001204{
1205 __assoc_sub_state* __state_;
1206
1207 explicit future(__assoc_sub_state* __state);
1208
1209 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001210 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001211
Howard Hinnantc834c512011-11-29 18:15:50 +00001212 template <class _R1, class _Fp>
1213 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1214 template <class _R1, class _Fp>
1215 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001216
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001217public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001218 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001219 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001220 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001221 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001222 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1223 future(const future&) = delete;
1224 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001226 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001227 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001228 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001229 return *this;
1230 }
Louis Dionne7b844362020-07-30 09:42:23 -04001231
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001232 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001233 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001234 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001235
1236 // retrieving the value
1237 void get();
1238
Howard Hinnant684902d2010-09-22 14:16:26 +00001239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001240 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001241
1242 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001243 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001244 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001245
Howard Hinnant684902d2010-09-22 14:16:26 +00001246 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001247 void wait() const {__state_->wait();}
1248 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001250 future_status
1251 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1252 {return __state_->wait_for(__rel_time);}
1253 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001255 future_status
1256 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1257 {return __state_->wait_until(__abs_time);}
1258};
1259
Howard Hinnantc834c512011-11-29 18:15:50 +00001260template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001261inline _LIBCPP_INLINE_VISIBILITY
1262void
Howard Hinnant22448042012-07-21 17:46:55 +00001263swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001264{
1265 __x.swap(__y);
1266}
1267
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001268// promise<R>
1269
Howard Hinnant944510a2011-06-14 19:58:17 +00001270template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001271
Howard Hinnantc834c512011-11-29 18:15:50 +00001272template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001273class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001274{
Howard Hinnantc834c512011-11-29 18:15:50 +00001275 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001276
Howard Hinnant684902d2010-09-22 14:16:26 +00001277 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001278 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001279
1280 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001281public:
1282 promise();
1283 template <class _Alloc>
1284 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001286 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001287 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1288 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001289 ~promise();
1290
1291 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001293 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001294 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001295 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001296 return *this;
1297 }
1298 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001299
Howard Hinnant684902d2010-09-22 14:16:26 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001301 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001302
1303 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001304 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001305
1306 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001307 void set_value(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001308 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001309 void set_exception(exception_ptr __p);
1310
1311 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001312 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001313 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001314 void set_exception_at_thread_exit(exception_ptr __p);
1315};
1316
Howard Hinnantc834c512011-11-29 18:15:50 +00001317template <class _Rp>
1318promise<_Rp>::promise()
1319 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001320{
1321}
1322
Howard Hinnantc834c512011-11-29 18:15:50 +00001323template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001324template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001325promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001326{
Eric Fiselier0d109272014-10-23 06:24:45 +00001327 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1328 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001329 typedef __allocator_destructor<_A2> _D2;
1330 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001331 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001332 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001333 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001334}
1335
Howard Hinnantc834c512011-11-29 18:15:50 +00001336template <class _Rp>
1337promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001338{
1339 if (__state_)
1340 {
1341 if (!__state_->__has_value() && __state_->use_count() > 1)
1342 __state_->set_exception(make_exception_ptr(
1343 future_error(make_error_code(future_errc::broken_promise))
1344 ));
1345 __state_->__release_shared();
1346 }
1347}
1348
Howard Hinnantc834c512011-11-29 18:15:50 +00001349template <class _Rp>
1350future<_Rp>
1351promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001352{
1353 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001354 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001355 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001356}
1357
Howard Hinnantc834c512011-11-29 18:15:50 +00001358template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001359void
Howard Hinnantc834c512011-11-29 18:15:50 +00001360promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001361{
1362 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001363 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001364 __state_->set_value(__r);
1365}
1366
Howard Hinnantc834c512011-11-29 18:15:50 +00001367template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001368void
Howard Hinnantc834c512011-11-29 18:15:50 +00001369promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001370{
1371 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001372 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001373 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001374}
1375
Howard Hinnantc834c512011-11-29 18:15:50 +00001376template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001377void
Howard Hinnantc834c512011-11-29 18:15:50 +00001378promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001379{
Marshall Clow2b36f572016-05-16 16:55:32 +00001380 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001381 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001382 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001383 __state_->set_exception(__p);
1384}
1385
Howard Hinnantc834c512011-11-29 18:15:50 +00001386template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001387void
Howard Hinnantc834c512011-11-29 18:15:50 +00001388promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001389{
1390 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001391 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001392 __state_->set_value_at_thread_exit(__r);
1393}
1394
Howard Hinnantc834c512011-11-29 18:15:50 +00001395template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001396void
Howard Hinnantc834c512011-11-29 18:15:50 +00001397promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001398{
1399 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001400 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001401 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001402}
1403
Howard Hinnantc834c512011-11-29 18:15:50 +00001404template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001405void
Howard Hinnantc834c512011-11-29 18:15:50 +00001406promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001407{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001408 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001409 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001410 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001411 __state_->set_exception_at_thread_exit(__p);
1412}
1413
1414// promise<R&>
1415
Howard Hinnantc834c512011-11-29 18:15:50 +00001416template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001417class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001418{
Howard Hinnantc834c512011-11-29 18:15:50 +00001419 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001420
Howard Hinnant684902d2010-09-22 14:16:26 +00001421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001422 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001423
1424 template <class> friend class packaged_task;
1425
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001426public:
1427 promise();
1428 template <class _Allocator>
1429 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001430 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001431 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001432 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1433 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001434 ~promise();
1435
1436 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001437 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001438 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001439 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001440 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001441 return *this;
1442 }
1443 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001444
Howard Hinnant684902d2010-09-22 14:16:26 +00001445 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001446 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001447
1448 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001449 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001450
1451 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001452 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001453 void set_exception(exception_ptr __p);
1454
1455 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001456 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001457 void set_exception_at_thread_exit(exception_ptr __p);
1458};
1459
Howard Hinnantc834c512011-11-29 18:15:50 +00001460template <class _Rp>
1461promise<_Rp&>::promise()
1462 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001463{
1464}
1465
Howard Hinnantc834c512011-11-29 18:15:50 +00001466template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001467template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001468promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001469{
Eric Fiselier0d109272014-10-23 06:24:45 +00001470 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1471 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001472 typedef __allocator_destructor<_A2> _D2;
1473 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001474 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001475 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001476 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001477}
1478
Howard Hinnantc834c512011-11-29 18:15:50 +00001479template <class _Rp>
1480promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001481{
1482 if (__state_)
1483 {
1484 if (!__state_->__has_value() && __state_->use_count() > 1)
1485 __state_->set_exception(make_exception_ptr(
1486 future_error(make_error_code(future_errc::broken_promise))
1487 ));
1488 __state_->__release_shared();
1489 }
1490}
1491
Howard Hinnantc834c512011-11-29 18:15:50 +00001492template <class _Rp>
1493future<_Rp&>
1494promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001495{
1496 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001497 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001498 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001499}
1500
Howard Hinnantc834c512011-11-29 18:15:50 +00001501template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001502void
Howard Hinnantc834c512011-11-29 18:15:50 +00001503promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504{
1505 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001506 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001507 __state_->set_value(__r);
1508}
1509
Howard Hinnantc834c512011-11-29 18:15:50 +00001510template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001511void
Howard Hinnantc834c512011-11-29 18:15:50 +00001512promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001513{
Marshall Clow2b36f572016-05-16 16:55:32 +00001514 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001515 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001516 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001517 __state_->set_exception(__p);
1518}
1519
Howard Hinnantc834c512011-11-29 18:15:50 +00001520template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001521void
Howard Hinnantc834c512011-11-29 18:15:50 +00001522promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001523{
1524 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001525 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001526 __state_->set_value_at_thread_exit(__r);
1527}
1528
Howard Hinnantc834c512011-11-29 18:15:50 +00001529template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001530void
Howard Hinnantc834c512011-11-29 18:15:50 +00001531promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001532{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001533 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001534 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001535 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001536 __state_->set_exception_at_thread_exit(__p);
1537}
1538
1539// promise<void>
1540
1541template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001542class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001543{
1544 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001545
Howard Hinnant684902d2010-09-22 14:16:26 +00001546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001547 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001548
1549 template <class> friend class packaged_task;
1550
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001551public:
1552 promise();
1553 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001554 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001555 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001557 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001558 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1559 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001560 ~promise();
1561
1562 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001564 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001565 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001566 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001567 return *this;
1568 }
1569 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001570
Howard Hinnant684902d2010-09-22 14:16:26 +00001571 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001572 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001573
1574 // retrieving the result
1575 future<void> get_future();
1576
1577 // setting the result
1578 void set_value();
1579 void set_exception(exception_ptr __p);
1580
1581 // setting the result with deferred notification
1582 void set_value_at_thread_exit();
1583 void set_exception_at_thread_exit(exception_ptr __p);
1584};
1585
1586template <class _Alloc>
1587promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1588{
Eric Fiselier0d109272014-10-23 06:24:45 +00001589 typedef __assoc_sub_state_alloc<_Alloc> _State;
1590 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001591 typedef __allocator_destructor<_A2> _D2;
1592 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001593 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001594 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001595 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001596}
1597
Howard Hinnantc834c512011-11-29 18:15:50 +00001598template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001599inline _LIBCPP_INLINE_VISIBILITY
1600void
Howard Hinnant22448042012-07-21 17:46:55 +00001601swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001602{
1603 __x.swap(__y);
1604}
1605
Howard Hinnantc834c512011-11-29 18:15:50 +00001606template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001607 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001608 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001609
Howard Hinnantccdd2032010-08-30 18:46:21 +00001610// packaged_task
1611
1612template<class _Fp> class __packaged_task_base;
1613
Howard Hinnantc834c512011-11-29 18:15:50 +00001614template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001615class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001616{
1617 __packaged_task_base(const __packaged_task_base&);
1618 __packaged_task_base& operator=(const __packaged_task_base&);
1619public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001620 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001621 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001623 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001624 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001625 virtual void destroy() = 0;
1626 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001627 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001628};
1629
1630template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1631
Howard Hinnantc834c512011-11-29 18:15:50 +00001632template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001633class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001634 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001635{
Howard Hinnantc834c512011-11-29 18:15:50 +00001636 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001637public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001638 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001639 explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001640 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001641 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001642 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001643 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001644 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001645 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001646 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001647 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001648 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001649 virtual void destroy();
1650 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001651 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001652};
1653
Howard Hinnantc834c512011-11-29 18:15:50 +00001654template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001655void
Howard Hinnantc834c512011-11-29 18:15:50 +00001656__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001657 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001658{
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001659 ::new ((void*)__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001660}
1661
Howard Hinnantc834c512011-11-29 18:15:50 +00001662template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001663void
Howard Hinnantc834c512011-11-29 18:15:50 +00001664__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001665{
Howard Hinnantc834c512011-11-29 18:15:50 +00001666 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001667}
1668
Howard Hinnantc834c512011-11-29 18:15:50 +00001669template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001670void
Howard Hinnantc834c512011-11-29 18:15:50 +00001671__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001672{
Eric Fiselier0d109272014-10-23 06:24:45 +00001673 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1674 typedef allocator_traits<_Ap> _ATraits;
1675 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001676 _Ap __a(__f_.second());
1677 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001678 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001679}
1680
Howard Hinnantc834c512011-11-29 18:15:50 +00001681template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1682_Rp
1683__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001684{
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05001685 return _VSTD::__invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001686}
1687
Howard Hinnant944510a2011-06-14 19:58:17 +00001688template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001689
Howard Hinnantc834c512011-11-29 18:15:50 +00001690template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001691class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001692{
Howard Hinnantc834c512011-11-29 18:15:50 +00001693 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001694
1695 _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
1696 __base* __get_buf() { return (__base*)&__buf_; }
1697
Howard Hinnant022c7482013-01-21 17:26:55 +00001698 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001699 __base* __f_;
1700
1701public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001702 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001703
1704 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001705 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001706 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001707 template<class _Fp>
1708 __packaged_task_function(_Fp&& __f);
1709 template<class _Fp, class _Alloc>
1710 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001711
Howard Hinnant22448042012-07-21 17:46:55 +00001712 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1713 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001714
1715 __packaged_task_function(const __packaged_task_function&) = delete;
1716 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1717
1718 ~__packaged_task_function();
1719
Howard Hinnant22448042012-07-21 17:46:55 +00001720 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001721
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001723 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001724};
1725
Howard Hinnantc834c512011-11-29 18:15:50 +00001726template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001727__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001728{
1729 if (__f.__f_ == nullptr)
1730 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001731 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001732 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001733 __f.__f_->__move_to(__get_buf());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001734 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001735 }
1736 else
1737 {
1738 __f_ = __f.__f_;
1739 __f.__f_ = nullptr;
1740 }
1741}
1742
Howard Hinnantc834c512011-11-29 18:15:50 +00001743template<class _Rp, class ..._ArgTypes>
1744template <class _Fp>
1745__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001746 : __f_(nullptr)
1747{
Marshall Clow733d60e2014-04-07 13:32:26 +00001748 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001749 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001750 if (sizeof(_FF) <= sizeof(__buf_))
1751 {
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001752 ::new ((void*)&__buf_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001753 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001754 }
1755 else
1756 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001757 typedef allocator<_FF> _Ap;
1758 _Ap __a;
1759 typedef __allocator_destructor<_Ap> _Dp;
1760 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001761 ::new ((void*)__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001762 __f_ = __hold.release();
1763 }
1764}
1765
Howard Hinnantc834c512011-11-29 18:15:50 +00001766template<class _Rp, class ..._ArgTypes>
1767template <class _Fp, class _Alloc>
1768__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1769 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001770 : __f_(nullptr)
1771{
Marshall Clow733d60e2014-04-07 13:32:26 +00001772 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001773 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001774 if (sizeof(_FF) <= sizeof(__buf_))
1775 {
1776 __f_ = (__base*)&__buf_;
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001777 ::new ((void*)__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001778 }
1779 else
1780 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001781 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001782 _Ap __a(__a0);
1783 typedef __allocator_destructor<_Ap> _Dp;
1784 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001785 ::new ((void*)_VSTD::addressof(*__hold.get()))
Eric Fiselier0d109272014-10-23 06:24:45 +00001786 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1787 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001788 }
1789}
1790
Howard Hinnantc834c512011-11-29 18:15:50 +00001791template<class _Rp, class ..._ArgTypes>
1792__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001793__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001794{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001795 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001796 __f_->destroy();
1797 else if (__f_)
1798 __f_->destroy_deallocate();
1799 __f_ = nullptr;
1800 if (__f.__f_ == nullptr)
1801 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001802 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001803 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001804 __f.__f_->__move_to(__get_buf());
1805 __f_ = __get_buf();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001806 }
1807 else
1808 {
1809 __f_ = __f.__f_;
1810 __f.__f_ = nullptr;
1811 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001812 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001813}
1814
Howard Hinnantc834c512011-11-29 18:15:50 +00001815template<class _Rp, class ..._ArgTypes>
1816__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001817{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001818 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001819 __f_->destroy();
1820 else if (__f_)
1821 __f_->destroy_deallocate();
1822}
1823
Howard Hinnantc834c512011-11-29 18:15:50 +00001824template<class _Rp, class ..._ArgTypes>
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001825_LIBCPP_NO_CFI
Howard Hinnantccdd2032010-08-30 18:46:21 +00001826void
Howard Hinnant22448042012-07-21 17:46:55 +00001827__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001828{
1829 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1830 {
1831 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1832 __base* __t = (__base*)&__tempbuf;
1833 __f_->__move_to(__t);
1834 __f_->destroy();
1835 __f_ = nullptr;
1836 __f.__f_->__move_to((__base*)&__buf_);
1837 __f.__f_->destroy();
1838 __f.__f_ = nullptr;
1839 __f_ = (__base*)&__buf_;
1840 __t->__move_to((__base*)&__f.__buf_);
1841 __t->destroy();
1842 __f.__f_ = (__base*)&__f.__buf_;
1843 }
1844 else if (__f_ == (__base*)&__buf_)
1845 {
1846 __f_->__move_to((__base*)&__f.__buf_);
1847 __f_->destroy();
1848 __f_ = __f.__f_;
1849 __f.__f_ = (__base*)&__f.__buf_;
1850 }
1851 else if (__f.__f_ == (__base*)&__f.__buf_)
1852 {
1853 __f.__f_->__move_to((__base*)&__buf_);
1854 __f.__f_->destroy();
1855 __f.__f_ = __f_;
1856 __f_ = (__base*)&__buf_;
1857 }
1858 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001859 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001860}
1861
Howard Hinnantc834c512011-11-29 18:15:50 +00001862template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001863inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001864_Rp
1865__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001866{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001867 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001868}
1869
Howard Hinnantc834c512011-11-29 18:15:50 +00001870template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001871class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001872{
1873public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00001874 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00001875
1876private:
1877 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1878 promise<result_type> __p_;
1879
1880public:
1881 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00001882 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001883 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00001884 template <class _Fp,
1885 class = typename enable_if
1886 <
1887 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001888 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00001889 packaged_task
1890 >::value
1891 >::type
1892 >
Howard Hinnant684902d2010-09-22 14:16:26 +00001893 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001894 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00001895 template <class _Fp, class _Allocator,
1896 class = typename enable_if
1897 <
1898 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001899 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00001900 packaged_task
1901 >::value
1902 >::type
1903 >
1904 _LIBCPP_INLINE_VISIBILITY
1905 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1906 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1907 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001908 // ~packaged_task() = default;
1909
1910 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00001911 packaged_task(const packaged_task&) = delete;
1912 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001913
1914 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00001915 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001916 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001917 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001918 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001919 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001920 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001921 __f_ = _VSTD::move(__other.__f_);
1922 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001923 return *this;
1924 }
Howard Hinnant684902d2010-09-22 14:16:26 +00001925 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001926 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001927 {
1928 __f_.swap(__other.__f_);
1929 __p_.swap(__other.__p_);
1930 }
1931
Howard Hinnant684902d2010-09-22 14:16:26 +00001932 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001933 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001934
1935 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00001936 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001937 future<result_type> get_future() {return __p_.get_future();}
1938
1939 // execution
1940 void operator()(_ArgTypes... __args);
1941 void make_ready_at_thread_exit(_ArgTypes... __args);
1942
1943 void reset();
1944};
1945
Howard Hinnantc834c512011-11-29 18:15:50 +00001946template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001947void
Howard Hinnantc834c512011-11-29 18:15:50 +00001948packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001949{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001950 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001951 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001952 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001953 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001954#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001955 try
1956 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001957#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001958 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001959#ifndef _LIBCPP_NO_EXCEPTIONS
1960 }
1961 catch (...)
1962 {
1963 __p_.set_exception(current_exception());
1964 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001965#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001966}
1967
Howard Hinnantc834c512011-11-29 18:15:50 +00001968template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001969void
Howard Hinnantc834c512011-11-29 18:15:50 +00001970packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001971{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001972 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001973 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001974 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001975 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001976#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001977 try
1978 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001979#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001980 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001981#ifndef _LIBCPP_NO_EXCEPTIONS
1982 }
1983 catch (...)
1984 {
1985 __p_.set_exception_at_thread_exit(current_exception());
1986 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001987#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001988}
1989
Howard Hinnantc834c512011-11-29 18:15:50 +00001990template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001991void
Howard Hinnantc834c512011-11-29 18:15:50 +00001992packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001993{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001994 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00001995 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001996 __p_ = promise<result_type>();
1997}
1998
1999template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002000class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002001{
2002public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002003 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004
2005private:
2006 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2007 promise<result_type> __p_;
2008
2009public:
2010 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002012 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002013 template <class _Fp,
2014 class = typename enable_if
2015 <
2016 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002017 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002018 packaged_task
2019 >::value
2020 >::type
2021 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002022 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002023 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002024 template <class _Fp, class _Allocator,
2025 class = typename enable_if
2026 <
2027 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002028 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002029 packaged_task
2030 >::value
2031 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002032 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002033 _LIBCPP_INLINE_VISIBILITY
2034 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2035 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2036 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002037 // ~packaged_task() = default;
2038
2039 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002040 packaged_task(const packaged_task&) = delete;
2041 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002042
2043 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002045 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002046 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002048 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002049 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002050 __f_ = _VSTD::move(__other.__f_);
2051 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002052 return *this;
2053 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002055 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002056 {
2057 __f_.swap(__other.__f_);
2058 __p_.swap(__other.__p_);
2059 }
2060
Howard Hinnant684902d2010-09-22 14:16:26 +00002061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002062 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002063
2064 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002066 future<result_type> get_future() {return __p_.get_future();}
2067
2068 // execution
2069 void operator()(_ArgTypes... __args);
2070 void make_ready_at_thread_exit(_ArgTypes... __args);
2071
2072 void reset();
2073};
2074
2075template<class ..._ArgTypes>
2076void
2077packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2078{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002079 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002080 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002082 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002083#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002084 try
2085 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002086#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002087 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002088 __p_.set_value();
2089#ifndef _LIBCPP_NO_EXCEPTIONS
2090 }
2091 catch (...)
2092 {
2093 __p_.set_exception(current_exception());
2094 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002095#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002096}
2097
2098template<class ..._ArgTypes>
2099void
2100packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2101{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002102 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002103 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002104 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002105 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002106#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002107 try
2108 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002109#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002110 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002111 __p_.set_value_at_thread_exit();
2112#ifndef _LIBCPP_NO_EXCEPTIONS
2113 }
2114 catch (...)
2115 {
2116 __p_.set_exception_at_thread_exit(current_exception());
2117 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002118#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002119}
2120
2121template<class ..._ArgTypes>
2122void
2123packaged_task<void(_ArgTypes...)>::reset()
2124{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002125 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002126 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002127 __p_ = promise<result_type>();
2128}
2129
jasonliubdad63b2021-03-24 22:31:58 +00002130template <class _Rp, class... _ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002131inline _LIBCPP_INLINE_VISIBILITY
2132void
jasonliubdad63b2021-03-24 22:31:58 +00002133swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002134{
2135 __x.swap(__y);
2136}
2137
Marshall Clowa0a057e2017-11-27 20:47:54 +00002138template <class _Callable, class _Alloc>
2139struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2140 : public true_type {};
2141
Howard Hinnantc834c512011-11-29 18:15:50 +00002142template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002143_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002144__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002145{
Howard Hinnantc834c512011-11-29 18:15:50 +00002146 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2147 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2148 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002149}
2150
Howard Hinnantc834c512011-11-29 18:15:50 +00002151template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002152_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002153__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002154{
Howard Hinnantc834c512011-11-29 18:15:50 +00002155 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2156 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2157 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2158 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002159}
2160
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002161#ifndef _LIBCPP_CXX03_LANG
2162
Howard Hinnantc834c512011-11-29 18:15:50 +00002163template <class _Fp, class... _Args>
Louis Dionne3b967d02019-12-10 18:00:42 -05002164class _LIBCPP_HIDDEN __async_func
Howard Hinnant95cfd872011-05-19 15:05:04 +00002165{
Howard Hinnantc834c512011-11-29 18:15:50 +00002166 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002167
2168public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002169 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002170
2171 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002172 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002173 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002174
2175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002176 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002177
Howard Hinnantc834c512011-11-29 18:15:50 +00002178 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002179 {
2180 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2181 return __execute(_Index());
2182 }
2183private:
2184 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002185 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002186 __execute(__tuple_indices<_Indices...>)
2187 {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002188 return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002189 }
2190};
2191
Marshall Clowd56a5b62013-11-03 22:06:53 +00002192inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002193{ return (int(__policy) & int(__value)) != 0; }
2194
Howard Hinnantc834c512011-11-29 18:15:50 +00002195template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002196_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002197future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2198async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002199{
Howard Hinnantc834c512011-11-29 18:15:50 +00002200 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2201 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002202
2203#ifndef _LIBCPP_NO_EXCEPTIONS
2204 try
2205 {
2206#endif
2207 if (__does_policy_contain(__policy, launch::async))
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002208 return _VSTD::__make_async_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
2209 _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002210#ifndef _LIBCPP_NO_EXCEPTIONS
2211 }
2212 catch ( ... ) { if (__policy == launch::async) throw ; }
2213#endif
2214
2215 if (__does_policy_contain(__policy, launch::deferred))
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002216 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
2217 _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002218 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002219}
2220
Howard Hinnantc834c512011-11-29 18:15:50 +00002221template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002222_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002223future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2224async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002225{
Howard Hinnantc834c512011-11-29 18:15:50 +00002226 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002227 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002228}
2229
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002230#endif // C++03
Howard Hinnantccdd2032010-08-30 18:46:21 +00002231
Howard Hinnante6a10852010-09-03 21:46:37 +00002232// shared_future
2233
Howard Hinnantc834c512011-11-29 18:15:50 +00002234template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002235class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002236{
Howard Hinnantc834c512011-11-29 18:15:50 +00002237 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002238
2239public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002241 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002242 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002243 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002244 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002246 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002247 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002249 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002250 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002251 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002252 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant684902d2010-09-22 14:16:26 +00002253 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002254 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002255 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002256 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002257 return *this;
2258 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002259
2260 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002261 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002262 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002263
Howard Hinnant684902d2010-09-22 14:16:26 +00002264 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002265 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002266
2267 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002268 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002269 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002270
Howard Hinnant684902d2010-09-22 14:16:26 +00002271 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002272 void wait() const {__state_->wait();}
2273 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002274 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002275 future_status
2276 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2277 {return __state_->wait_for(__rel_time);}
2278 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002279 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002280 future_status
2281 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2282 {return __state_->wait_until(__abs_time);}
2283};
2284
Howard Hinnantc834c512011-11-29 18:15:50 +00002285template <class _Rp>
2286shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002287{
2288 if (__state_)
2289 __state_->__release_shared();
2290}
2291
Howard Hinnantc834c512011-11-29 18:15:50 +00002292template <class _Rp>
2293shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002294shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002295{
2296 if (__rhs.__state_)
2297 __rhs.__state_->__add_shared();
2298 if (__state_)
2299 __state_->__release_shared();
2300 __state_ = __rhs.__state_;
2301 return *this;
2302}
2303
Howard Hinnantc834c512011-11-29 18:15:50 +00002304template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002305class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002306{
Howard Hinnantc834c512011-11-29 18:15:50 +00002307 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002308
2309public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002311 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002312 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002313 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2314 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002316 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002317 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002319 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002320 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002321 ~shared_future();
2322 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002324 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002325 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002326 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002327 return *this;
2328 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002329
2330 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002331 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002332 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002333
Howard Hinnant684902d2010-09-22 14:16:26 +00002334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002335 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002336
2337 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002338 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002339 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002340
Howard Hinnant684902d2010-09-22 14:16:26 +00002341 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002342 void wait() const {__state_->wait();}
2343 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002344 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002345 future_status
2346 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2347 {return __state_->wait_for(__rel_time);}
2348 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002349 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002350 future_status
2351 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2352 {return __state_->wait_until(__abs_time);}
2353};
2354
Howard Hinnantc834c512011-11-29 18:15:50 +00002355template <class _Rp>
2356shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002357{
2358 if (__state_)
2359 __state_->__release_shared();
2360}
2361
Howard Hinnantc834c512011-11-29 18:15:50 +00002362template <class _Rp>
2363shared_future<_Rp&>&
2364shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002365{
2366 if (__rhs.__state_)
2367 __rhs.__state_->__add_shared();
2368 if (__state_)
2369 __state_->__release_shared();
2370 __state_ = __rhs.__state_;
2371 return *this;
2372}
2373
2374template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002375class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002376{
2377 __assoc_sub_state* __state_;
2378
2379public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002381 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002383 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2384 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002386 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002387 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002389 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002390 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002391 ~shared_future();
2392 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002393 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002394 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002395 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002396 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002397 return *this;
2398 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002399
2400 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002402 void get() const {__state_->copy();}
2403
Howard Hinnant684902d2010-09-22 14:16:26 +00002404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002405 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002406
2407 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002408 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002409 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002410
Howard Hinnant684902d2010-09-22 14:16:26 +00002411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002412 void wait() const {__state_->wait();}
2413 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002414 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002415 future_status
2416 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2417 {return __state_->wait_for(__rel_time);}
2418 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002419 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002420 future_status
2421 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2422 {return __state_->wait_until(__abs_time);}
2423};
2424
Howard Hinnantc834c512011-11-29 18:15:50 +00002425template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002426inline _LIBCPP_INLINE_VISIBILITY
2427void
Howard Hinnant22448042012-07-21 17:46:55 +00002428swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002429{
2430 __x.swap(__y);
2431}
2432
Howard Hinnantc834c512011-11-29 18:15:50 +00002433template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002434inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002435shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002436future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002437{
Howard Hinnantc834c512011-11-29 18:15:50 +00002438 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002439}
2440
Howard Hinnantc834c512011-11-29 18:15:50 +00002441template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002442inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002443shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002444future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002445{
Howard Hinnantc834c512011-11-29 18:15:50 +00002446 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002447}
2448
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002449inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002450shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002451future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002452{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002453 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002454}
2455
Howard Hinnantc51e1022010-05-11 19:42:16 +00002456_LIBCPP_END_NAMESPACE_STD
2457
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002458#endif // !_LIBCPP_HAS_NO_THREADS
2459
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002460#endif // _LIBCPP_FUTURE