blob: db60ab69ecadbe49b49e73a96cdace3be74ad1fc [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
364#include <__config>
Louis Dionne73912b22020-11-04 15:01:25 -0500365#include <__availability>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000366#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000375#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000377#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000378#error <future> is not supported on this single threaded system
379#else // !_LIBCPP_HAS_NO_THREADS
380
Howard Hinnantc51e1022010-05-11 19:42:16 +0000381_LIBCPP_BEGIN_NAMESPACE_STD
382
383//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000384_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000385{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000386 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000388 no_state,
389 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000391_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000392
Howard Hinnant684902d2010-09-22 14:16:26 +0000393template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000394struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000395
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000396#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000398struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000399#endif
400
Howard Hinnantc51e1022010-05-11 19:42:16 +0000401//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000402_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000403{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000404 async = 1,
405 deferred = 2,
406 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000409
Howard Hinnantda760a82013-06-29 18:38:17 +0000410#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411
Howard Hinnantda760a82013-06-29 18:38:17 +0000412typedef underlying_type<launch>::type __launch_underlying_type;
Howard Hinnantda760a82013-06-29 18:38:17 +0000413
414inline _LIBCPP_INLINE_VISIBILITY
415_LIBCPP_CONSTEXPR
416launch
417operator&(launch __x, launch __y)
418{
419 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
420 static_cast<__launch_underlying_type>(__y));
421}
422
423inline _LIBCPP_INLINE_VISIBILITY
424_LIBCPP_CONSTEXPR
425launch
426operator|(launch __x, launch __y)
427{
428 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
429 static_cast<__launch_underlying_type>(__y));
430}
431
432inline _LIBCPP_INLINE_VISIBILITY
433_LIBCPP_CONSTEXPR
434launch
435operator^(launch __x, launch __y)
436{
437 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
438 static_cast<__launch_underlying_type>(__y));
439}
440
441inline _LIBCPP_INLINE_VISIBILITY
442_LIBCPP_CONSTEXPR
443launch
444operator~(launch __x)
445{
Howard Hinnant373d7602013-07-02 18:01:41 +0000446 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000447}
448
449inline _LIBCPP_INLINE_VISIBILITY
450launch&
451operator&=(launch& __x, launch __y)
452{
453 __x = __x & __y; return __x;
454}
455
456inline _LIBCPP_INLINE_VISIBILITY
457launch&
458operator|=(launch& __x, launch __y)
459{
460 __x = __x | __y; return __x;
461}
462
463inline _LIBCPP_INLINE_VISIBILITY
464launch&
465operator^=(launch& __x, launch __y)
466{
467 __x = __x ^ __y; return __x;
468}
469
470#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
471
Howard Hinnantc51e1022010-05-11 19:42:16 +0000472//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000473_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000475 ready,
476 timeout,
477 deferred
478};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000479_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000480
Howard Hinnant8331b762013-03-06 23:30:19 +0000481_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000482const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000483
484inline _LIBCPP_INLINE_VISIBILITY
485error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000486make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000487{
488 return error_code(static_cast<int>(__e), future_category());
489}
490
491inline _LIBCPP_INLINE_VISIBILITY
492error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000493make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000494{
495 return error_condition(static_cast<int>(__e), future_category());
496}
497
Mehdi Amini228053d2017-05-04 17:08:54 +0000498class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000499 : public logic_error
500{
501 error_code __ec_;
502public:
503 future_error(error_code __ec);
Marshall Clowd4a669c2016-11-14 18:56:24 +0000504#if _LIBCPP_STD_VERS > 14
505 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
506#endif
Howard Hinnant684902d2010-09-22 14:16:26 +0000507 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000508 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000509
Dimitry Andric47269ce2020-03-13 19:36:26 +0100510 future_error(const future_error&) _NOEXCEPT = default;
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000511 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000512};
513
Louis Dionne16fe2952018-07-11 23:14:33 +0000514_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000515#ifndef _LIBCPP_NO_EXCEPTIONS
516_LIBCPP_AVAILABILITY_FUTURE_ERROR
517#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000518void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000519{
520#ifndef _LIBCPP_NO_EXCEPTIONS
521 throw future_error(make_error_code(_Ev));
522#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000523 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000524 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000525#endif
526}
527
Mehdi Amini228053d2017-05-04 17:08:54 +0000528class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000529 : public __shared_count
530{
531protected:
532 exception_ptr __exception_;
533 mutable mutex __mut_;
534 mutable condition_variable __cv_;
535 unsigned __state_;
536
Howard Hinnant719bda32011-05-28 14:41:13 +0000537 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000538 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000539public:
540 enum
541 {
542 __constructed = 1,
543 __future_attached = 2,
544 ready = 4,
545 deferred = 8
546 };
547
Howard Hinnant684902d2010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000549 __assoc_sub_state() : __state_(0) {}
550
Howard Hinnant684902d2010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000552 bool __has_value() const
553 {return (__state_ & __constructed) || (__exception_ != nullptr);}
554
Howard Hinnant684902d2010-09-22 14:16:26 +0000555 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000556 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000557 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000558 bool __has_future_attached = (__state_ & __future_attached) != 0;
559 if (__has_future_attached)
560 __throw_future_error(future_errc::future_already_retrieved);
561 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000562 __state_ |= __future_attached;
563 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000564
Howard Hinnant684902d2010-09-22 14:16:26 +0000565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000566 void __set_deferred() {__state_ |= deferred;}
567
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000568 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000569 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000570 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000571
572 void set_value();
573 void set_value_at_thread_exit();
574
575 void set_exception(exception_ptr __p);
576 void set_exception_at_thread_exit(exception_ptr __p);
577
578 void copy();
579
Howard Hinnantccdd2032010-08-30 18:46:21 +0000580 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000581 template <class _Rep, class _Period>
582 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000583 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000584 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
585 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000586 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000587 future_status
588 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000589
590 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000591};
592
Howard Hinnantf4712b92010-08-28 21:01:06 +0000593template <class _Clock, class _Duration>
594future_status
595__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
596{
597 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000598 if (__state_ & deferred)
599 return future_status::deferred;
600 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000601 __cv_.wait_until(__lk, __abs_time);
602 if (__state_ & ready)
603 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000604 return future_status::timeout;
605}
606
607template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000608inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000609future_status
610__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
611{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000612 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000613}
614
Howard Hinnantc834c512011-11-29 18:15:50 +0000615template <class _Rp>
Louis Dionne3b967d02019-12-10 18:00:42 -0500616class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000617 : public __assoc_sub_state
618{
619 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000620 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000621protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000622 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000623
Howard Hinnant719bda32011-05-28 14:41:13 +0000624 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000625public:
626
627 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400628 void set_value(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000629
630 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400631 void set_value_at_thread_exit(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000632
Howard Hinnantc834c512011-11-29 18:15:50 +0000633 _Rp move();
634 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000635};
636
Howard Hinnantc834c512011-11-29 18:15:50 +0000637template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000638void
Howard Hinnantc834c512011-11-29 18:15:50 +0000639__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000640{
641 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000642 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000643 delete this;
644}
645
Howard Hinnantc834c512011-11-29 18:15:50 +0000646template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000647template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000648_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000649void
Howard Hinnantc834c512011-11-29 18:15:50 +0000650__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000651{
652 unique_lock<mutex> __lk(this->__mut_);
653 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000654 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500655 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000656 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000657 __cv_.notify_all();
658}
659
Howard Hinnantc834c512011-11-29 18:15:50 +0000660template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000661template <class _Arg>
662void
Howard Hinnantc834c512011-11-29 18:15:50 +0000663__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000664{
665 unique_lock<mutex> __lk(this->__mut_);
666 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000667 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500668 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000669 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000670 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000671}
672
Howard Hinnantc834c512011-11-29 18:15:50 +0000673template <class _Rp>
674_Rp
675__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000676{
677 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000678 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000679 if (this->__exception_ != nullptr)
680 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000681 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000682}
683
Howard Hinnantc834c512011-11-29 18:15:50 +0000684template <class _Rp>
685typename add_lvalue_reference<_Rp>::type
686__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000687{
688 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000689 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000690 if (this->__exception_ != nullptr)
691 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000692 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000693}
694
Howard Hinnantc834c512011-11-29 18:15:50 +0000695template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000696class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000697 : public __assoc_sub_state
698{
699 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000700 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000701protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000702 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000703
Howard Hinnant719bda32011-05-28 14:41:13 +0000704 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000705public:
706
Howard Hinnantc834c512011-11-29 18:15:50 +0000707 void set_value(_Rp& __arg);
708 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000709
Howard Hinnantc834c512011-11-29 18:15:50 +0000710 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000711};
712
Howard Hinnantc834c512011-11-29 18:15:50 +0000713template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000714void
Howard Hinnantc834c512011-11-29 18:15:50 +0000715__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000716{
717 delete this;
718}
719
Howard Hinnantc834c512011-11-29 18:15:50 +0000720template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000721void
Howard Hinnantc834c512011-11-29 18:15:50 +0000722__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000723{
724 unique_lock<mutex> __lk(this->__mut_);
725 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000726 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000727 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000729 __cv_.notify_all();
730}
731
Howard Hinnantc834c512011-11-29 18:15:50 +0000732template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000733void
Howard Hinnantc834c512011-11-29 18:15:50 +0000734__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000735{
736 unique_lock<mutex> __lk(this->__mut_);
737 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000738 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000739 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000740 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000741 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000742}
743
Howard Hinnantc834c512011-11-29 18:15:50 +0000744template <class _Rp>
745_Rp&
746__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000747{
748 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000749 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000750 if (this->__exception_ != nullptr)
751 rethrow_exception(this->__exception_);
752 return *__value_;
753}
754
Howard Hinnantc834c512011-11-29 18:15:50 +0000755template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000756class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000757 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000758{
Howard Hinnantc834c512011-11-29 18:15:50 +0000759 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000760 _Alloc __alloc_;
761
Howard Hinnant719bda32011-05-28 14:41:13 +0000762 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000763public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000764 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000765 explicit __assoc_state_alloc(const _Alloc& __a)
766 : __alloc_(__a) {}
767};
768
Howard Hinnantc834c512011-11-29 18:15:50 +0000769template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000770void
Howard Hinnantc834c512011-11-29 18:15:50 +0000771__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000772{
773 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000774 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000775 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
776 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000777 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000778 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000779 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000780 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000781}
782
Howard Hinnantc834c512011-11-29 18:15:50 +0000783template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000784class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000785 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000786{
Howard Hinnantc834c512011-11-29 18:15:50 +0000787 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000788 _Alloc __alloc_;
789
Howard Hinnant719bda32011-05-28 14:41:13 +0000790 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000791public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000792 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000793 explicit __assoc_state_alloc(const _Alloc& __a)
794 : __alloc_(__a) {}
795};
796
Howard Hinnantc834c512011-11-29 18:15:50 +0000797template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000798void
Howard Hinnantc834c512011-11-29 18:15:50 +0000799__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000800{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000801 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
802 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000803 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000804 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000805 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000806 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000807}
808
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000809template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000810class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000811 : public __assoc_sub_state
812{
813 typedef __assoc_sub_state base;
814 _Alloc __alloc_;
815
Howard Hinnant719bda32011-05-28 14:41:13 +0000816 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000817public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000818 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000819 explicit __assoc_sub_state_alloc(const _Alloc& __a)
820 : __alloc_(__a) {}
821};
822
823template <class _Alloc>
824void
Howard Hinnant719bda32011-05-28 14:41:13 +0000825__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000826{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000827 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
828 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000829 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000830 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000831 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000832 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000833}
834
Howard Hinnantc834c512011-11-29 18:15:50 +0000835template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000836class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000837 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000838{
Howard Hinnantc834c512011-11-29 18:15:50 +0000839 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000840
Howard Hinnantc834c512011-11-29 18:15:50 +0000841 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000842
843public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000844 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000845 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000846
847 virtual void __execute();
848};
849
Howard Hinnantc834c512011-11-29 18:15:50 +0000850template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000851inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000852__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
853 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000854{
855 this->__set_deferred();
856}
857
Howard Hinnantc834c512011-11-29 18:15:50 +0000858template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000859void
Howard Hinnantc834c512011-11-29 18:15:50 +0000860__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000861{
862#ifndef _LIBCPP_NO_EXCEPTIONS
863 try
864 {
865#endif // _LIBCPP_NO_EXCEPTIONS
866 this->set_value(__func_());
867#ifndef _LIBCPP_NO_EXCEPTIONS
868 }
869 catch (...)
870 {
871 this->set_exception(current_exception());
872 }
873#endif // _LIBCPP_NO_EXCEPTIONS
874}
875
Howard Hinnantc834c512011-11-29 18:15:50 +0000876template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000877class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000878 : public __assoc_sub_state
879{
880 typedef __assoc_sub_state base;
881
Howard Hinnantc834c512011-11-29 18:15:50 +0000882 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000883
884public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000885 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000886 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000887
888 virtual void __execute();
889};
890
Howard Hinnantc834c512011-11-29 18:15:50 +0000891template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000892inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000893__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
894 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000895{
896 this->__set_deferred();
897}
898
Howard Hinnantc834c512011-11-29 18:15:50 +0000899template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000900void
Howard Hinnantc834c512011-11-29 18:15:50 +0000901__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000902{
903#ifndef _LIBCPP_NO_EXCEPTIONS
904 try
905 {
906#endif // _LIBCPP_NO_EXCEPTIONS
907 __func_();
908 this->set_value();
909#ifndef _LIBCPP_NO_EXCEPTIONS
910 }
911 catch (...)
912 {
913 this->set_exception(current_exception());
914 }
915#endif // _LIBCPP_NO_EXCEPTIONS
916}
917
Howard Hinnantc834c512011-11-29 18:15:50 +0000918template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000919class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000920 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000921{
Howard Hinnantc834c512011-11-29 18:15:50 +0000922 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000923
Howard Hinnantc834c512011-11-29 18:15:50 +0000924 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000925
Howard Hinnant719bda32011-05-28 14:41:13 +0000926 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000927public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000928 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000929 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000930
931 virtual void __execute();
932};
933
Howard Hinnantc834c512011-11-29 18:15:50 +0000934template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000935inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000936__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
937 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000938{
939}
940
Howard Hinnantc834c512011-11-29 18:15:50 +0000941template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000942void
Howard Hinnantc834c512011-11-29 18:15:50 +0000943__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000944{
945#ifndef _LIBCPP_NO_EXCEPTIONS
946 try
947 {
948#endif // _LIBCPP_NO_EXCEPTIONS
949 this->set_value(__func_());
950#ifndef _LIBCPP_NO_EXCEPTIONS
951 }
952 catch (...)
953 {
954 this->set_exception(current_exception());
955 }
956#endif // _LIBCPP_NO_EXCEPTIONS
957}
958
Howard Hinnantc834c512011-11-29 18:15:50 +0000959template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000960void
Howard Hinnantc834c512011-11-29 18:15:50 +0000961__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000962{
963 this->wait();
964 base::__on_zero_shared();
965}
966
Howard Hinnantc834c512011-11-29 18:15:50 +0000967template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000968class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000969 : public __assoc_sub_state
970{
971 typedef __assoc_sub_state base;
972
Howard Hinnantc834c512011-11-29 18:15:50 +0000973 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000974
Howard Hinnant719bda32011-05-28 14:41:13 +0000975 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000976public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000978 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000979
980 virtual void __execute();
981};
982
Howard Hinnantc834c512011-11-29 18:15:50 +0000983template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000984inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000985__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
986 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000987{
988}
989
Howard Hinnantc834c512011-11-29 18:15:50 +0000990template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000991void
Howard Hinnantc834c512011-11-29 18:15:50 +0000992__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000993{
994#ifndef _LIBCPP_NO_EXCEPTIONS
995 try
996 {
997#endif // _LIBCPP_NO_EXCEPTIONS
998 __func_();
999 this->set_value();
1000#ifndef _LIBCPP_NO_EXCEPTIONS
1001 }
1002 catch (...)
1003 {
1004 this->set_exception(current_exception());
1005 }
1006#endif // _LIBCPP_NO_EXCEPTIONS
1007}
1008
Howard Hinnantc834c512011-11-29 18:15:50 +00001009template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001010void
Howard Hinnantc834c512011-11-29 18:15:50 +00001011__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001012{
1013 this->wait();
1014 base::__on_zero_shared();
1015}
1016
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001017template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1018template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001019
1020// future
1021
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001022template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001023
Howard Hinnantc834c512011-11-29 18:15:50 +00001024template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001025_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001026__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001027
Howard Hinnantc834c512011-11-29 18:15:50 +00001028template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001029_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001030__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001031
Howard Hinnantc834c512011-11-29 18:15:50 +00001032template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001033class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001034{
Howard Hinnantc834c512011-11-29 18:15:50 +00001035 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001036
Howard Hinnantc834c512011-11-29 18:15:50 +00001037 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001038
1039 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001040 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001041
Howard Hinnantc834c512011-11-29 18:15:50 +00001042 template <class _R1, class _Fp>
1043 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1044 template <class _R1, class _Fp>
1045 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001046
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001047public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001049 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001050 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001051 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001052 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1053 future(const future&) = delete;
1054 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001055 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001056 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001057 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001058 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001059 return *this;
1060 }
Louis Dionne7b844362020-07-30 09:42:23 -04001061
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001062 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001063 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001064 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001065
1066 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001067 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001068
Howard Hinnant684902d2010-09-22 14:16:26 +00001069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001070 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001071
1072 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001074 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001075
Howard Hinnant684902d2010-09-22 14:16:26 +00001076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001077 void wait() const {__state_->wait();}
1078 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001079 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001080 future_status
1081 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1082 {return __state_->wait_for(__rel_time);}
1083 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001084 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001085 future_status
1086 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1087 {return __state_->wait_until(__abs_time);}
1088};
1089
Howard Hinnantc834c512011-11-29 18:15:50 +00001090template <class _Rp>
1091future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001092 : __state_(__state)
1093{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001094 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001095}
1096
Howard Hinnantccdd2032010-08-30 18:46:21 +00001097struct __release_shared_count
1098{
1099 void operator()(__shared_count* p) {p->__release_shared();}
1100};
1101
Howard Hinnantc834c512011-11-29 18:15:50 +00001102template <class _Rp>
1103future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001104{
1105 if (__state_)
1106 __state_->__release_shared();
1107}
1108
Howard Hinnantc834c512011-11-29 18:15:50 +00001109template <class _Rp>
1110_Rp
1111future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001112{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001113 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001114 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001115 __state_ = nullptr;
1116 return __s->move();
1117}
1118
Howard Hinnantc834c512011-11-29 18:15:50 +00001119template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001120class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001121{
Howard Hinnantc834c512011-11-29 18:15:50 +00001122 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001123
Howard Hinnantc834c512011-11-29 18:15:50 +00001124 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001125
1126 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001127 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001128
Howard Hinnantc834c512011-11-29 18:15:50 +00001129 template <class _R1, class _Fp>
1130 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1131 template <class _R1, class _Fp>
1132 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001133
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001134public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001136 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001137 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001138 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001139 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1140 future(const future&) = delete;
1141 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001142 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001143 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001144 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001145 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001146 return *this;
1147 }
Louis Dionne7b844362020-07-30 09:42:23 -04001148
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001149 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001150 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001151 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001152
1153 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001154 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001155
Howard Hinnant684902d2010-09-22 14:16:26 +00001156 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001157 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001158
1159 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001160 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001161 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001162
Howard Hinnant684902d2010-09-22 14:16:26 +00001163 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001164 void wait() const {__state_->wait();}
1165 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001166 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001167 future_status
1168 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1169 {return __state_->wait_for(__rel_time);}
1170 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001171 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001172 future_status
1173 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1174 {return __state_->wait_until(__abs_time);}
1175};
1176
Howard Hinnantc834c512011-11-29 18:15:50 +00001177template <class _Rp>
1178future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001179 : __state_(__state)
1180{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001181 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001182}
1183
Howard Hinnantc834c512011-11-29 18:15:50 +00001184template <class _Rp>
1185future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001186{
1187 if (__state_)
1188 __state_->__release_shared();
1189}
1190
Howard Hinnantc834c512011-11-29 18:15:50 +00001191template <class _Rp>
1192_Rp&
1193future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001194{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001195 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001196 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001197 __state_ = nullptr;
1198 return __s->copy();
1199}
1200
1201template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001202class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001203{
1204 __assoc_sub_state* __state_;
1205
1206 explicit future(__assoc_sub_state* __state);
1207
1208 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001209 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001210
Howard Hinnantc834c512011-11-29 18:15:50 +00001211 template <class _R1, class _Fp>
1212 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1213 template <class _R1, class _Fp>
1214 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001215
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001216public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001217 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001218 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001219 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001220 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001221 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1222 future(const future&) = delete;
1223 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001224 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001225 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001226 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001227 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001228 return *this;
1229 }
Louis Dionne7b844362020-07-30 09:42:23 -04001230
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001231 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001232 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001233 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001234
1235 // retrieving the value
1236 void get();
1237
Howard Hinnant684902d2010-09-22 14:16:26 +00001238 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001239 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001240
1241 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001243 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001244
Howard Hinnant684902d2010-09-22 14:16:26 +00001245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001246 void wait() const {__state_->wait();}
1247 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001249 future_status
1250 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1251 {return __state_->wait_for(__rel_time);}
1252 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001253 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001254 future_status
1255 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1256 {return __state_->wait_until(__abs_time);}
1257};
1258
Howard Hinnantc834c512011-11-29 18:15:50 +00001259template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001260inline _LIBCPP_INLINE_VISIBILITY
1261void
Howard Hinnant22448042012-07-21 17:46:55 +00001262swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001263{
1264 __x.swap(__y);
1265}
1266
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001267// promise<R>
1268
Howard Hinnant944510a2011-06-14 19:58:17 +00001269template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001270
Howard Hinnantc834c512011-11-29 18:15:50 +00001271template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001272class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001273{
Howard Hinnantc834c512011-11-29 18:15:50 +00001274 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001275
Howard Hinnant684902d2010-09-22 14:16:26 +00001276 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001277 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001278
1279 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001280public:
1281 promise();
1282 template <class _Alloc>
1283 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001284 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001285 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001286 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1287 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001288 ~promise();
1289
1290 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001291 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001292 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001293 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001294 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001295 return *this;
1296 }
1297 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001298
Howard Hinnant684902d2010-09-22 14:16:26 +00001299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001300 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001301
1302 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001303 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001304
1305 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001306 void set_value(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001307 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001308 void set_exception(exception_ptr __p);
1309
1310 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001311 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001312 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001313 void set_exception_at_thread_exit(exception_ptr __p);
1314};
1315
Howard Hinnantc834c512011-11-29 18:15:50 +00001316template <class _Rp>
1317promise<_Rp>::promise()
1318 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001319{
1320}
1321
Howard Hinnantc834c512011-11-29 18:15:50 +00001322template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001323template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001324promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001325{
Eric Fiselier0d109272014-10-23 06:24:45 +00001326 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1327 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001328 typedef __allocator_destructor<_A2> _D2;
1329 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001330 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001331 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001332 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001333}
1334
Howard Hinnantc834c512011-11-29 18:15:50 +00001335template <class _Rp>
1336promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001337{
1338 if (__state_)
1339 {
1340 if (!__state_->__has_value() && __state_->use_count() > 1)
1341 __state_->set_exception(make_exception_ptr(
1342 future_error(make_error_code(future_errc::broken_promise))
1343 ));
1344 __state_->__release_shared();
1345 }
1346}
1347
Howard Hinnantc834c512011-11-29 18:15:50 +00001348template <class _Rp>
1349future<_Rp>
1350promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001351{
1352 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001353 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001354 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001355}
1356
Howard Hinnantc834c512011-11-29 18:15:50 +00001357template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001358void
Howard Hinnantc834c512011-11-29 18:15:50 +00001359promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001360{
1361 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001362 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001363 __state_->set_value(__r);
1364}
1365
Howard Hinnantc834c512011-11-29 18:15:50 +00001366template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001367void
Howard Hinnantc834c512011-11-29 18:15:50 +00001368promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001369{
1370 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001371 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001372 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001373}
1374
Howard Hinnantc834c512011-11-29 18:15:50 +00001375template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001376void
Howard Hinnantc834c512011-11-29 18:15:50 +00001377promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001378{
Marshall Clow2b36f572016-05-16 16:55:32 +00001379 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001380 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001381 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001382 __state_->set_exception(__p);
1383}
1384
Howard Hinnantc834c512011-11-29 18:15:50 +00001385template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001386void
Howard Hinnantc834c512011-11-29 18:15:50 +00001387promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001388{
1389 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001390 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001391 __state_->set_value_at_thread_exit(__r);
1392}
1393
Howard Hinnantc834c512011-11-29 18:15:50 +00001394template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001395void
Howard Hinnantc834c512011-11-29 18:15:50 +00001396promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001397{
1398 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001399 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001400 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001401}
1402
Howard Hinnantc834c512011-11-29 18:15:50 +00001403template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001404void
Howard Hinnantc834c512011-11-29 18:15:50 +00001405promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001406{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001407 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001408 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001409 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001410 __state_->set_exception_at_thread_exit(__p);
1411}
1412
1413// promise<R&>
1414
Howard Hinnantc834c512011-11-29 18:15:50 +00001415template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001416class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001417{
Howard Hinnantc834c512011-11-29 18:15:50 +00001418 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001419
Howard Hinnant684902d2010-09-22 14:16:26 +00001420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001421 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001422
1423 template <class> friend class packaged_task;
1424
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001425public:
1426 promise();
1427 template <class _Allocator>
1428 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001429 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001430 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001431 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1432 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001433 ~promise();
1434
1435 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001436 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001437 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001438 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001439 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001440 return *this;
1441 }
1442 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001443
Howard Hinnant684902d2010-09-22 14:16:26 +00001444 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001445 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001446
1447 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001448 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001449
1450 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001451 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001452 void set_exception(exception_ptr __p);
1453
1454 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001455 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001456 void set_exception_at_thread_exit(exception_ptr __p);
1457};
1458
Howard Hinnantc834c512011-11-29 18:15:50 +00001459template <class _Rp>
1460promise<_Rp&>::promise()
1461 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001462{
1463}
1464
Howard Hinnantc834c512011-11-29 18:15:50 +00001465template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001466template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001467promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001468{
Eric Fiselier0d109272014-10-23 06:24:45 +00001469 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1470 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001471 typedef __allocator_destructor<_A2> _D2;
1472 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001473 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001474 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001475 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001476}
1477
Howard Hinnantc834c512011-11-29 18:15:50 +00001478template <class _Rp>
1479promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001480{
1481 if (__state_)
1482 {
1483 if (!__state_->__has_value() && __state_->use_count() > 1)
1484 __state_->set_exception(make_exception_ptr(
1485 future_error(make_error_code(future_errc::broken_promise))
1486 ));
1487 __state_->__release_shared();
1488 }
1489}
1490
Howard Hinnantc834c512011-11-29 18:15:50 +00001491template <class _Rp>
1492future<_Rp&>
1493promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001494{
1495 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001496 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001497 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001498}
1499
Howard Hinnantc834c512011-11-29 18:15:50 +00001500template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001501void
Howard Hinnantc834c512011-11-29 18:15:50 +00001502promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001503{
1504 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001505 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001506 __state_->set_value(__r);
1507}
1508
Howard Hinnantc834c512011-11-29 18:15:50 +00001509template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001510void
Howard Hinnantc834c512011-11-29 18:15:50 +00001511promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001512{
Marshall Clow2b36f572016-05-16 16:55:32 +00001513 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001514 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001515 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001516 __state_->set_exception(__p);
1517}
1518
Howard Hinnantc834c512011-11-29 18:15:50 +00001519template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001520void
Howard Hinnantc834c512011-11-29 18:15:50 +00001521promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001522{
1523 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001524 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001525 __state_->set_value_at_thread_exit(__r);
1526}
1527
Howard Hinnantc834c512011-11-29 18:15:50 +00001528template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001529void
Howard Hinnantc834c512011-11-29 18:15:50 +00001530promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001531{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001532 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001533 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001534 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001535 __state_->set_exception_at_thread_exit(__p);
1536}
1537
1538// promise<void>
1539
1540template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001541class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001542{
1543 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001544
Howard Hinnant684902d2010-09-22 14:16:26 +00001545 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001546 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001547
1548 template <class> friend class packaged_task;
1549
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001550public:
1551 promise();
1552 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001553 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001554 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001556 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001557 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1558 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001559 ~promise();
1560
1561 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001562 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001563 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001564 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001565 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001566 return *this;
1567 }
1568 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001569
Howard Hinnant684902d2010-09-22 14:16:26 +00001570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001571 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001572
1573 // retrieving the result
1574 future<void> get_future();
1575
1576 // setting the result
1577 void set_value();
1578 void set_exception(exception_ptr __p);
1579
1580 // setting the result with deferred notification
1581 void set_value_at_thread_exit();
1582 void set_exception_at_thread_exit(exception_ptr __p);
1583};
1584
1585template <class _Alloc>
1586promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1587{
Eric Fiselier0d109272014-10-23 06:24:45 +00001588 typedef __assoc_sub_state_alloc<_Alloc> _State;
1589 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001590 typedef __allocator_destructor<_A2> _D2;
1591 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001592 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001593 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001594 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001595}
1596
Howard Hinnantc834c512011-11-29 18:15:50 +00001597template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001598inline _LIBCPP_INLINE_VISIBILITY
1599void
Howard Hinnant22448042012-07-21 17:46:55 +00001600swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001601{
1602 __x.swap(__y);
1603}
1604
Howard Hinnantc834c512011-11-29 18:15:50 +00001605template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001606 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001607 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001608
Howard Hinnantccdd2032010-08-30 18:46:21 +00001609// packaged_task
1610
1611template<class _Fp> class __packaged_task_base;
1612
Howard Hinnantc834c512011-11-29 18:15:50 +00001613template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001614class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001615{
1616 __packaged_task_base(const __packaged_task_base&);
1617 __packaged_task_base& operator=(const __packaged_task_base&);
1618public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001619 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001620 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001621 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001622 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001623 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001624 virtual void destroy() = 0;
1625 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001626 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001627};
1628
1629template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1630
Howard Hinnantc834c512011-11-29 18:15:50 +00001631template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001632class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001633 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001634{
Howard Hinnantc834c512011-11-29 18:15:50 +00001635 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001636public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001637 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001638 explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001639 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001640 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001642 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001643 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001644 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001645 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001646 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001647 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001648 virtual void destroy();
1649 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001650 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001651};
1652
Howard Hinnantc834c512011-11-29 18:15:50 +00001653template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001654void
Howard Hinnantc834c512011-11-29 18:15:50 +00001655__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001656 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001657{
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001658 ::new ((void*)__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001659}
1660
Howard Hinnantc834c512011-11-29 18:15:50 +00001661template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001662void
Howard Hinnantc834c512011-11-29 18:15:50 +00001663__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001664{
Howard Hinnantc834c512011-11-29 18:15:50 +00001665 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001666}
1667
Howard Hinnantc834c512011-11-29 18:15:50 +00001668template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001669void
Howard Hinnantc834c512011-11-29 18:15:50 +00001670__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001671{
Eric Fiselier0d109272014-10-23 06:24:45 +00001672 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1673 typedef allocator_traits<_Ap> _ATraits;
1674 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001675 _Ap __a(__f_.second());
1676 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001677 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001678}
1679
Howard Hinnantc834c512011-11-29 18:15:50 +00001680template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1681_Rp
1682__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001683{
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05001684 return _VSTD::__invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001685}
1686
Howard Hinnant944510a2011-06-14 19:58:17 +00001687template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001688
Howard Hinnantc834c512011-11-29 18:15:50 +00001689template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001690class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001691{
Howard Hinnantc834c512011-11-29 18:15:50 +00001692 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001693
1694 _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
1695 __base* __get_buf() { return (__base*)&__buf_; }
1696
Howard Hinnant022c7482013-01-21 17:26:55 +00001697 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001698 __base* __f_;
1699
1700public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001701 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001702
1703 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001705 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001706 template<class _Fp>
1707 __packaged_task_function(_Fp&& __f);
1708 template<class _Fp, class _Alloc>
1709 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001710
Howard Hinnant22448042012-07-21 17:46:55 +00001711 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1712 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001713
1714 __packaged_task_function(const __packaged_task_function&) = delete;
1715 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1716
1717 ~__packaged_task_function();
1718
Howard Hinnant22448042012-07-21 17:46:55 +00001719 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001720
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001722 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001723};
1724
Howard Hinnantc834c512011-11-29 18:15:50 +00001725template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001726__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001727{
1728 if (__f.__f_ == nullptr)
1729 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001730 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001731 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001732 __f.__f_->__move_to(__get_buf());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001733 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001734 }
1735 else
1736 {
1737 __f_ = __f.__f_;
1738 __f.__f_ = nullptr;
1739 }
1740}
1741
Howard Hinnantc834c512011-11-29 18:15:50 +00001742template<class _Rp, class ..._ArgTypes>
1743template <class _Fp>
1744__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001745 : __f_(nullptr)
1746{
Marshall Clow733d60e2014-04-07 13:32:26 +00001747 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001748 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001749 if (sizeof(_FF) <= sizeof(__buf_))
1750 {
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001751 ::new ((void*)&__buf_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001752 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001753 }
1754 else
1755 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001756 typedef allocator<_FF> _Ap;
1757 _Ap __a;
1758 typedef __allocator_destructor<_Ap> _Dp;
1759 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001760 ::new ((void*)__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001761 __f_ = __hold.release();
1762 }
1763}
1764
Howard Hinnantc834c512011-11-29 18:15:50 +00001765template<class _Rp, class ..._ArgTypes>
1766template <class _Fp, class _Alloc>
1767__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1768 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001769 : __f_(nullptr)
1770{
Marshall Clow733d60e2014-04-07 13:32:26 +00001771 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001772 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001773 if (sizeof(_FF) <= sizeof(__buf_))
1774 {
1775 __f_ = (__base*)&__buf_;
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001776 ::new ((void*)__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001777 }
1778 else
1779 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001780 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001781 _Ap __a(__a0);
1782 typedef __allocator_destructor<_Ap> _Dp;
1783 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001784 ::new ((void*)_VSTD::addressof(*__hold.get()))
Eric Fiselier0d109272014-10-23 06:24:45 +00001785 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1786 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001787 }
1788}
1789
Howard Hinnantc834c512011-11-29 18:15:50 +00001790template<class _Rp, class ..._ArgTypes>
1791__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001792__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001793{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001794 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001795 __f_->destroy();
1796 else if (__f_)
1797 __f_->destroy_deallocate();
1798 __f_ = nullptr;
1799 if (__f.__f_ == nullptr)
1800 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001801 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001802 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001803 __f.__f_->__move_to(__get_buf());
1804 __f_ = __get_buf();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001805 }
1806 else
1807 {
1808 __f_ = __f.__f_;
1809 __f.__f_ = nullptr;
1810 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001811 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001812}
1813
Howard Hinnantc834c512011-11-29 18:15:50 +00001814template<class _Rp, class ..._ArgTypes>
1815__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001816{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001817 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001818 __f_->destroy();
1819 else if (__f_)
1820 __f_->destroy_deallocate();
1821}
1822
Howard Hinnantc834c512011-11-29 18:15:50 +00001823template<class _Rp, class ..._ArgTypes>
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001824_LIBCPP_NO_CFI
Howard Hinnantccdd2032010-08-30 18:46:21 +00001825void
Howard Hinnant22448042012-07-21 17:46:55 +00001826__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001827{
1828 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1829 {
1830 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1831 __base* __t = (__base*)&__tempbuf;
1832 __f_->__move_to(__t);
1833 __f_->destroy();
1834 __f_ = nullptr;
1835 __f.__f_->__move_to((__base*)&__buf_);
1836 __f.__f_->destroy();
1837 __f.__f_ = nullptr;
1838 __f_ = (__base*)&__buf_;
1839 __t->__move_to((__base*)&__f.__buf_);
1840 __t->destroy();
1841 __f.__f_ = (__base*)&__f.__buf_;
1842 }
1843 else if (__f_ == (__base*)&__buf_)
1844 {
1845 __f_->__move_to((__base*)&__f.__buf_);
1846 __f_->destroy();
1847 __f_ = __f.__f_;
1848 __f.__f_ = (__base*)&__f.__buf_;
1849 }
1850 else if (__f.__f_ == (__base*)&__f.__buf_)
1851 {
1852 __f.__f_->__move_to((__base*)&__buf_);
1853 __f.__f_->destroy();
1854 __f.__f_ = __f_;
1855 __f_ = (__base*)&__buf_;
1856 }
1857 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001858 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001859}
1860
Howard Hinnantc834c512011-11-29 18:15:50 +00001861template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001862inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001863_Rp
1864__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001865{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001866 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001867}
1868
Howard Hinnantc834c512011-11-29 18:15:50 +00001869template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001870class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001871{
1872public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00001873 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00001874
1875private:
1876 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1877 promise<result_type> __p_;
1878
1879public:
1880 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00001881 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001882 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00001883 template <class _Fp,
1884 class = typename enable_if
1885 <
1886 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001887 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00001888 packaged_task
1889 >::value
1890 >::type
1891 >
Howard Hinnant684902d2010-09-22 14:16:26 +00001892 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001893 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00001894 template <class _Fp, class _Allocator,
1895 class = typename enable_if
1896 <
1897 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001898 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00001899 packaged_task
1900 >::value
1901 >::type
1902 >
1903 _LIBCPP_INLINE_VISIBILITY
1904 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1905 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1906 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001907 // ~packaged_task() = default;
1908
1909 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00001910 packaged_task(const packaged_task&) = delete;
1911 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001912
1913 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00001914 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001915 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001916 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001917 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001918 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001919 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001920 __f_ = _VSTD::move(__other.__f_);
1921 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001922 return *this;
1923 }
Howard Hinnant684902d2010-09-22 14:16:26 +00001924 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001925 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001926 {
1927 __f_.swap(__other.__f_);
1928 __p_.swap(__other.__p_);
1929 }
1930
Howard Hinnant684902d2010-09-22 14:16:26 +00001931 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001932 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001933
1934 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00001935 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001936 future<result_type> get_future() {return __p_.get_future();}
1937
1938 // execution
1939 void operator()(_ArgTypes... __args);
1940 void make_ready_at_thread_exit(_ArgTypes... __args);
1941
1942 void reset();
1943};
1944
Howard Hinnantc834c512011-11-29 18:15:50 +00001945template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001946void
Howard Hinnantc834c512011-11-29 18:15:50 +00001947packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001948{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001949 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001950 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001951 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001952 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001953#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001954 try
1955 {
1956#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001957 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001958#ifndef _LIBCPP_NO_EXCEPTIONS
1959 }
1960 catch (...)
1961 {
1962 __p_.set_exception(current_exception());
1963 }
1964#endif // _LIBCPP_NO_EXCEPTIONS
1965}
1966
Howard Hinnantc834c512011-11-29 18:15:50 +00001967template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001968void
Howard Hinnantc834c512011-11-29 18:15:50 +00001969packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001970{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001971 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001972 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001973 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001974 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001975#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001976 try
1977 {
1978#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001979 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001980#ifndef _LIBCPP_NO_EXCEPTIONS
1981 }
1982 catch (...)
1983 {
1984 __p_.set_exception_at_thread_exit(current_exception());
1985 }
1986#endif // _LIBCPP_NO_EXCEPTIONS
1987}
1988
Howard Hinnantc834c512011-11-29 18:15:50 +00001989template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001990void
Howard Hinnantc834c512011-11-29 18:15:50 +00001991packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001992{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001993 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00001994 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001995 __p_ = promise<result_type>();
1996}
1997
1998template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001999class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002000{
2001public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002002 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002003
2004private:
2005 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2006 promise<result_type> __p_;
2007
2008public:
2009 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002010 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002011 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002012 template <class _Fp,
2013 class = typename enable_if
2014 <
2015 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002016 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002017 packaged_task
2018 >::value
2019 >::type
2020 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002021 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002022 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002023 template <class _Fp, class _Allocator,
2024 class = typename enable_if
2025 <
2026 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002027 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002028 packaged_task
2029 >::value
2030 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002031 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002032 _LIBCPP_INLINE_VISIBILITY
2033 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2034 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2035 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002036 // ~packaged_task() = default;
2037
2038 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002039 packaged_task(const packaged_task&) = delete;
2040 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002041
2042 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002043 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002044 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002045 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002046 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002047 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002048 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002049 __f_ = _VSTD::move(__other.__f_);
2050 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002051 return *this;
2052 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002053 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002054 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002055 {
2056 __f_.swap(__other.__f_);
2057 __p_.swap(__other.__p_);
2058 }
2059
Howard Hinnant684902d2010-09-22 14:16:26 +00002060 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002061 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002062
2063 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002065 future<result_type> get_future() {return __p_.get_future();}
2066
2067 // execution
2068 void operator()(_ArgTypes... __args);
2069 void make_ready_at_thread_exit(_ArgTypes... __args);
2070
2071 void reset();
2072};
2073
2074template<class ..._ArgTypes>
2075void
2076packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2077{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002078 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002079 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002080 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002081 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002082#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002083 try
2084 {
2085#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002086 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002087 __p_.set_value();
2088#ifndef _LIBCPP_NO_EXCEPTIONS
2089 }
2090 catch (...)
2091 {
2092 __p_.set_exception(current_exception());
2093 }
2094#endif // _LIBCPP_NO_EXCEPTIONS
2095}
2096
2097template<class ..._ArgTypes>
2098void
2099packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2100{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002101 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002102 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002103 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002104 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002105#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002106 try
2107 {
2108#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002109 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002110 __p_.set_value_at_thread_exit();
2111#ifndef _LIBCPP_NO_EXCEPTIONS
2112 }
2113 catch (...)
2114 {
2115 __p_.set_exception_at_thread_exit(current_exception());
2116 }
2117#endif // _LIBCPP_NO_EXCEPTIONS
2118}
2119
2120template<class ..._ArgTypes>
2121void
2122packaged_task<void(_ArgTypes...)>::reset()
2123{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002124 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002125 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002126 __p_ = promise<result_type>();
2127}
2128
2129template <class _Callable>
2130inline _LIBCPP_INLINE_VISIBILITY
2131void
Howard Hinnant22448042012-07-21 17:46:55 +00002132swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002133{
2134 __x.swap(__y);
2135}
2136
Marshall Clowa0a057e2017-11-27 20:47:54 +00002137template <class _Callable, class _Alloc>
2138struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2139 : public true_type {};
2140
Howard Hinnantc834c512011-11-29 18:15:50 +00002141template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002142_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002143__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002144{
Howard Hinnantc834c512011-11-29 18:15:50 +00002145 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2146 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2147 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002148}
2149
Howard Hinnantc834c512011-11-29 18:15:50 +00002150template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002151_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002152__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002153{
Howard Hinnantc834c512011-11-29 18:15:50 +00002154 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2155 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2156 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2157 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002158}
2159
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002160#ifndef _LIBCPP_CXX03_LANG
2161
Howard Hinnantc834c512011-11-29 18:15:50 +00002162template <class _Fp, class... _Args>
Louis Dionne3b967d02019-12-10 18:00:42 -05002163class _LIBCPP_HIDDEN __async_func
Howard Hinnant95cfd872011-05-19 15:05:04 +00002164{
Howard Hinnantc834c512011-11-29 18:15:50 +00002165 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002166
2167public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002168 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002169
2170 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002171 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002172 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002173
2174 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002175 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002176
Howard Hinnantc834c512011-11-29 18:15:50 +00002177 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002178 {
2179 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2180 return __execute(_Index());
2181 }
2182private:
2183 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002184 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002185 __execute(__tuple_indices<_Indices...>)
2186 {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002187 return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002188 }
2189};
2190
Marshall Clowd56a5b62013-11-03 22:06:53 +00002191inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002192{ return (int(__policy) & int(__value)) != 0; }
2193
Howard Hinnantc834c512011-11-29 18:15:50 +00002194template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002195_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002196future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2197async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002198{
Howard Hinnantc834c512011-11-29 18:15:50 +00002199 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2200 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002201
2202#ifndef _LIBCPP_NO_EXCEPTIONS
2203 try
2204 {
2205#endif
2206 if (__does_policy_contain(__policy, launch::async))
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002207 return _VSTD::__make_async_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
2208 _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002209#ifndef _LIBCPP_NO_EXCEPTIONS
2210 }
2211 catch ( ... ) { if (__policy == launch::async) throw ; }
2212#endif
2213
2214 if (__does_policy_contain(__policy, launch::deferred))
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002215 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
2216 _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002217 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002218}
2219
Howard Hinnantc834c512011-11-29 18:15:50 +00002220template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002221_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002222future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2223async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002224{
Howard Hinnantc834c512011-11-29 18:15:50 +00002225 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002226 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002227}
2228
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002229#endif // C++03
Howard Hinnantccdd2032010-08-30 18:46:21 +00002230
Howard Hinnante6a10852010-09-03 21:46:37 +00002231// shared_future
2232
Howard Hinnantc834c512011-11-29 18:15:50 +00002233template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002234class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002235{
Howard Hinnantc834c512011-11-29 18:15:50 +00002236 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002237
2238public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002240 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002241 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002242 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002243 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002245 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002246 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002248 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002249 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002250 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002251 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant684902d2010-09-22 14:16:26 +00002252 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002253 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002254 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002255 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002256 return *this;
2257 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002258
2259 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002260 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002261 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002262
Howard Hinnant684902d2010-09-22 14:16:26 +00002263 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002264 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002265
2266 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002268 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002269
Howard Hinnant684902d2010-09-22 14:16:26 +00002270 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002271 void wait() const {__state_->wait();}
2272 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002273 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002274 future_status
2275 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2276 {return __state_->wait_for(__rel_time);}
2277 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002278 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002279 future_status
2280 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2281 {return __state_->wait_until(__abs_time);}
2282};
2283
Howard Hinnantc834c512011-11-29 18:15:50 +00002284template <class _Rp>
2285shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002286{
2287 if (__state_)
2288 __state_->__release_shared();
2289}
2290
Howard Hinnantc834c512011-11-29 18:15:50 +00002291template <class _Rp>
2292shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002293shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002294{
2295 if (__rhs.__state_)
2296 __rhs.__state_->__add_shared();
2297 if (__state_)
2298 __state_->__release_shared();
2299 __state_ = __rhs.__state_;
2300 return *this;
2301}
2302
Howard Hinnantc834c512011-11-29 18:15:50 +00002303template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002304class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002305{
Howard Hinnantc834c512011-11-29 18:15:50 +00002306 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002307
2308public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002310 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002312 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2313 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002315 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002316 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002318 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002319 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002320 ~shared_future();
2321 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002322 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002323 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002324 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002325 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002326 return *this;
2327 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002328
2329 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002331 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002332
Howard Hinnant684902d2010-09-22 14:16:26 +00002333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002334 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002335
2336 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002337 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002338 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002339
Howard Hinnant684902d2010-09-22 14:16:26 +00002340 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002341 void wait() const {__state_->wait();}
2342 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002344 future_status
2345 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2346 {return __state_->wait_for(__rel_time);}
2347 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002348 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002349 future_status
2350 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2351 {return __state_->wait_until(__abs_time);}
2352};
2353
Howard Hinnantc834c512011-11-29 18:15:50 +00002354template <class _Rp>
2355shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002356{
2357 if (__state_)
2358 __state_->__release_shared();
2359}
2360
Howard Hinnantc834c512011-11-29 18:15:50 +00002361template <class _Rp>
2362shared_future<_Rp&>&
2363shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002364{
2365 if (__rhs.__state_)
2366 __rhs.__state_->__add_shared();
2367 if (__state_)
2368 __state_->__release_shared();
2369 __state_ = __rhs.__state_;
2370 return *this;
2371}
2372
2373template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002374class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002375{
2376 __assoc_sub_state* __state_;
2377
2378public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002379 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002380 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002381 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002382 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2383 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002385 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002386 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002388 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002389 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002390 ~shared_future();
2391 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002392 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002393 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002394 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002395 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002396 return *this;
2397 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002398
2399 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002401 void get() const {__state_->copy();}
2402
Howard Hinnant684902d2010-09-22 14:16:26 +00002403 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002404 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002405
2406 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002408 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002409
Howard Hinnant684902d2010-09-22 14:16:26 +00002410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002411 void wait() const {__state_->wait();}
2412 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002414 future_status
2415 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2416 {return __state_->wait_for(__rel_time);}
2417 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002418 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002419 future_status
2420 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2421 {return __state_->wait_until(__abs_time);}
2422};
2423
Howard Hinnantc834c512011-11-29 18:15:50 +00002424template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002425inline _LIBCPP_INLINE_VISIBILITY
2426void
Howard Hinnant22448042012-07-21 17:46:55 +00002427swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002428{
2429 __x.swap(__y);
2430}
2431
Howard Hinnantc834c512011-11-29 18:15:50 +00002432template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002433inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002434shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002435future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002436{
Howard Hinnantc834c512011-11-29 18:15:50 +00002437 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002438}
2439
Howard Hinnantc834c512011-11-29 18:15:50 +00002440template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002441inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002442shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002443future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002444{
Howard Hinnantc834c512011-11-29 18:15:50 +00002445 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002446}
2447
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002448inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002449shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002450future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002451{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002452 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002453}
2454
Howard Hinnantc51e1022010-05-11 19:42:16 +00002455_LIBCPP_END_NAMESPACE_STD
2456
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002457#endif // !_LIBCPP_HAS_NO_THREADS
2458
Howard Hinnantc51e1022010-05-11 19:42:16 +00002459#endif // _LIBCPP_FUTURE