blob: 483266dddec4e25cb2c36e1fe8c0033b2b98e981 [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>
365#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000366#include <memory>
367#include <chrono>
368#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000369#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000370#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000371
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000372#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000373#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000374#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000375
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000376#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000377#error <future> is not supported on this single threaded system
378#else // !_LIBCPP_HAS_NO_THREADS
379
Howard Hinnantc51e1022010-05-11 19:42:16 +0000380_LIBCPP_BEGIN_NAMESPACE_STD
381
382//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000383_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000384{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000385 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000387 no_state,
388 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000389};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000390_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000391
Howard Hinnant684902d2010-09-22 14:16:26 +0000392template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000393struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000394
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000395#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
396template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000397struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000398#endif
399
Howard Hinnantc51e1022010-05-11 19:42:16 +0000400//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000401_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000402{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000403 async = 1,
404 deferred = 2,
405 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000406};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000407_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000408
Howard Hinnantda760a82013-06-29 18:38:17 +0000409#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
410
Howard Hinnantda760a82013-06-29 18:38:17 +0000411typedef underlying_type<launch>::type __launch_underlying_type;
Howard Hinnantda760a82013-06-29 18:38:17 +0000412
413inline _LIBCPP_INLINE_VISIBILITY
414_LIBCPP_CONSTEXPR
415launch
416operator&(launch __x, launch __y)
417{
418 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
419 static_cast<__launch_underlying_type>(__y));
420}
421
422inline _LIBCPP_INLINE_VISIBILITY
423_LIBCPP_CONSTEXPR
424launch
425operator|(launch __x, launch __y)
426{
427 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
428 static_cast<__launch_underlying_type>(__y));
429}
430
431inline _LIBCPP_INLINE_VISIBILITY
432_LIBCPP_CONSTEXPR
433launch
434operator^(launch __x, launch __y)
435{
436 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
437 static_cast<__launch_underlying_type>(__y));
438}
439
440inline _LIBCPP_INLINE_VISIBILITY
441_LIBCPP_CONSTEXPR
442launch
443operator~(launch __x)
444{
Howard Hinnant373d7602013-07-02 18:01:41 +0000445 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000446}
447
448inline _LIBCPP_INLINE_VISIBILITY
449launch&
450operator&=(launch& __x, launch __y)
451{
452 __x = __x & __y; return __x;
453}
454
455inline _LIBCPP_INLINE_VISIBILITY
456launch&
457operator|=(launch& __x, launch __y)
458{
459 __x = __x | __y; return __x;
460}
461
462inline _LIBCPP_INLINE_VISIBILITY
463launch&
464operator^=(launch& __x, launch __y)
465{
466 __x = __x ^ __y; return __x;
467}
468
469#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
470
Howard Hinnantc51e1022010-05-11 19:42:16 +0000471//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000472_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000473{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474 ready,
475 timeout,
476 deferred
477};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000478_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479
Howard Hinnant8331b762013-03-06 23:30:19 +0000480_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000481const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000482
483inline _LIBCPP_INLINE_VISIBILITY
484error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000485make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000486{
487 return error_code(static_cast<int>(__e), future_category());
488}
489
490inline _LIBCPP_INLINE_VISIBILITY
491error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000492make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000493{
494 return error_condition(static_cast<int>(__e), future_category());
495}
496
Mehdi Amini228053d2017-05-04 17:08:54 +0000497class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000498 : public logic_error
499{
500 error_code __ec_;
501public:
502 future_error(error_code __ec);
Marshall Clowd4a669c2016-11-14 18:56:24 +0000503#if _LIBCPP_STD_VERS > 14
504 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
505#endif
Howard Hinnant684902d2010-09-22 14:16:26 +0000506 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000507 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000508
Dimitry Andric47269ce2020-03-13 19:36:26 +0100509 future_error(const future_error&) _NOEXCEPT = default;
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000510 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000511};
512
Louis Dionne16fe2952018-07-11 23:14:33 +0000513_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000514#ifndef _LIBCPP_NO_EXCEPTIONS
515_LIBCPP_AVAILABILITY_FUTURE_ERROR
516#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000517void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000518{
519#ifndef _LIBCPP_NO_EXCEPTIONS
520 throw future_error(make_error_code(_Ev));
521#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000522 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000523 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000524#endif
525}
526
Mehdi Amini228053d2017-05-04 17:08:54 +0000527class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000528 : public __shared_count
529{
530protected:
531 exception_ptr __exception_;
532 mutable mutex __mut_;
533 mutable condition_variable __cv_;
534 unsigned __state_;
535
Howard Hinnant719bda32011-05-28 14:41:13 +0000536 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000537 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000538public:
539 enum
540 {
541 __constructed = 1,
542 __future_attached = 2,
543 ready = 4,
544 deferred = 8
545 };
546
Howard Hinnant684902d2010-09-22 14:16:26 +0000547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000548 __assoc_sub_state() : __state_(0) {}
549
Howard Hinnant684902d2010-09-22 14:16:26 +0000550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000551 bool __has_value() const
552 {return (__state_ & __constructed) || (__exception_ != nullptr);}
553
Howard Hinnant684902d2010-09-22 14:16:26 +0000554 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000555 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000556 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000557 bool __has_future_attached = (__state_ & __future_attached) != 0;
558 if (__has_future_attached)
559 __throw_future_error(future_errc::future_already_retrieved);
560 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000561 __state_ |= __future_attached;
562 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000563
Howard Hinnant684902d2010-09-22 14:16:26 +0000564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000565 void __set_deferred() {__state_ |= deferred;}
566
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000568 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000569 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000570
571 void set_value();
572 void set_value_at_thread_exit();
573
574 void set_exception(exception_ptr __p);
575 void set_exception_at_thread_exit(exception_ptr __p);
576
577 void copy();
578
Howard Hinnantccdd2032010-08-30 18:46:21 +0000579 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000580 template <class _Rep, class _Period>
581 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000583 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
584 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000585 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000586 future_status
587 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000588
589 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000590};
591
Howard Hinnantf4712b92010-08-28 21:01:06 +0000592template <class _Clock, class _Duration>
593future_status
594__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
595{
596 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000597 if (__state_ & deferred)
598 return future_status::deferred;
599 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000600 __cv_.wait_until(__lk, __abs_time);
601 if (__state_ & ready)
602 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000603 return future_status::timeout;
604}
605
606template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000607inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000608future_status
609__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
610{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000611 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000612}
613
Howard Hinnantc834c512011-11-29 18:15:50 +0000614template <class _Rp>
Louis Dionne3b967d02019-12-10 18:00:42 -0500615class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000616 : public __assoc_sub_state
617{
618 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000619 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000621 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000622
Howard Hinnant719bda32011-05-28 14:41:13 +0000623 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000624public:
625
626 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400627 void set_value(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000628
629 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400630 void set_value_at_thread_exit(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000631
Howard Hinnantc834c512011-11-29 18:15:50 +0000632 _Rp move();
633 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000634};
635
Howard Hinnantc834c512011-11-29 18:15:50 +0000636template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000637void
Howard Hinnantc834c512011-11-29 18:15:50 +0000638__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000639{
640 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000641 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000642 delete this;
643}
644
Howard Hinnantc834c512011-11-29 18:15:50 +0000645template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000646template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000647_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000648void
Howard Hinnantc834c512011-11-29 18:15:50 +0000649__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000650{
651 unique_lock<mutex> __lk(this->__mut_);
652 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000653 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000654 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000655 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000656 __cv_.notify_all();
657}
658
Howard Hinnantc834c512011-11-29 18:15:50 +0000659template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000660template <class _Arg>
661void
Howard Hinnantc834c512011-11-29 18:15:50 +0000662__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000663{
664 unique_lock<mutex> __lk(this->__mut_);
665 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000666 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000667 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000668 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000669 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000670}
671
Howard Hinnantc834c512011-11-29 18:15:50 +0000672template <class _Rp>
673_Rp
674__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675{
676 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000677 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000678 if (this->__exception_ != nullptr)
679 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000680 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000681}
682
Howard Hinnantc834c512011-11-29 18:15:50 +0000683template <class _Rp>
684typename add_lvalue_reference<_Rp>::type
685__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000686{
687 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000688 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000689 if (this->__exception_ != nullptr)
690 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000691 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000692}
693
Howard Hinnantc834c512011-11-29 18:15:50 +0000694template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000695class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000696 : public __assoc_sub_state
697{
698 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000699 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000700protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000701 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000702
Howard Hinnant719bda32011-05-28 14:41:13 +0000703 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000704public:
705
Howard Hinnantc834c512011-11-29 18:15:50 +0000706 void set_value(_Rp& __arg);
707 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000708
Howard Hinnantc834c512011-11-29 18:15:50 +0000709 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000710};
711
Howard Hinnantc834c512011-11-29 18:15:50 +0000712template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000713void
Howard Hinnantc834c512011-11-29 18:15:50 +0000714__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715{
716 delete this;
717}
718
Howard Hinnantc834c512011-11-29 18:15:50 +0000719template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000720void
Howard Hinnantc834c512011-11-29 18:15:50 +0000721__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000722{
723 unique_lock<mutex> __lk(this->__mut_);
724 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000725 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000726 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000727 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728 __cv_.notify_all();
729}
730
Howard Hinnantc834c512011-11-29 18:15:50 +0000731template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000732void
Howard Hinnantc834c512011-11-29 18:15:50 +0000733__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000734{
735 unique_lock<mutex> __lk(this->__mut_);
736 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000737 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000738 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000739 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000740 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000741}
742
Howard Hinnantc834c512011-11-29 18:15:50 +0000743template <class _Rp>
744_Rp&
745__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000746{
747 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000748 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000749 if (this->__exception_ != nullptr)
750 rethrow_exception(this->__exception_);
751 return *__value_;
752}
753
Howard Hinnantc834c512011-11-29 18:15:50 +0000754template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000755class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000756 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000757{
Howard Hinnantc834c512011-11-29 18:15:50 +0000758 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000759 _Alloc __alloc_;
760
Howard Hinnant719bda32011-05-28 14:41:13 +0000761 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000762public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000763 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000764 explicit __assoc_state_alloc(const _Alloc& __a)
765 : __alloc_(__a) {}
766};
767
Howard Hinnantc834c512011-11-29 18:15:50 +0000768template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000769void
Howard Hinnantc834c512011-11-29 18:15:50 +0000770__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000771{
772 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000773 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000774 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
775 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000776 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000777 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000778 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000779 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000780}
781
Howard Hinnantc834c512011-11-29 18:15:50 +0000782template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000783class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000784 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000785{
Howard Hinnantc834c512011-11-29 18:15:50 +0000786 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000787 _Alloc __alloc_;
788
Howard Hinnant719bda32011-05-28 14:41:13 +0000789 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000790public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000791 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000792 explicit __assoc_state_alloc(const _Alloc& __a)
793 : __alloc_(__a) {}
794};
795
Howard Hinnantc834c512011-11-29 18:15:50 +0000796template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000797void
Howard Hinnantc834c512011-11-29 18:15:50 +0000798__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000799{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000800 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
801 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000802 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000803 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000804 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000805 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000806}
807
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000808template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000809class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000810 : public __assoc_sub_state
811{
812 typedef __assoc_sub_state base;
813 _Alloc __alloc_;
814
Howard Hinnant719bda32011-05-28 14:41:13 +0000815 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000816public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000817 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000818 explicit __assoc_sub_state_alloc(const _Alloc& __a)
819 : __alloc_(__a) {}
820};
821
822template <class _Alloc>
823void
Howard Hinnant719bda32011-05-28 14:41:13 +0000824__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000825{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000826 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
827 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000828 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000829 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000830 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000831 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000832}
833
Howard Hinnantc834c512011-11-29 18:15:50 +0000834template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000835class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000836 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000837{
Howard Hinnantc834c512011-11-29 18:15:50 +0000838 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000839
Howard Hinnantc834c512011-11-29 18:15:50 +0000840 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000841
842public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000843 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000844 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000845
846 virtual void __execute();
847};
848
Howard Hinnantc834c512011-11-29 18:15:50 +0000849template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000850inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000851__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
852 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000853{
854 this->__set_deferred();
855}
856
Howard Hinnantc834c512011-11-29 18:15:50 +0000857template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000858void
Howard Hinnantc834c512011-11-29 18:15:50 +0000859__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000860{
861#ifndef _LIBCPP_NO_EXCEPTIONS
862 try
863 {
864#endif // _LIBCPP_NO_EXCEPTIONS
865 this->set_value(__func_());
866#ifndef _LIBCPP_NO_EXCEPTIONS
867 }
868 catch (...)
869 {
870 this->set_exception(current_exception());
871 }
872#endif // _LIBCPP_NO_EXCEPTIONS
873}
874
Howard Hinnantc834c512011-11-29 18:15:50 +0000875template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000876class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000877 : public __assoc_sub_state
878{
879 typedef __assoc_sub_state base;
880
Howard Hinnantc834c512011-11-29 18:15:50 +0000881 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000882
883public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000884 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000885 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000886
887 virtual void __execute();
888};
889
Howard Hinnantc834c512011-11-29 18:15:50 +0000890template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000891inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000892__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
893 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000894{
895 this->__set_deferred();
896}
897
Howard Hinnantc834c512011-11-29 18:15:50 +0000898template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000899void
Howard Hinnantc834c512011-11-29 18:15:50 +0000900__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000901{
902#ifndef _LIBCPP_NO_EXCEPTIONS
903 try
904 {
905#endif // _LIBCPP_NO_EXCEPTIONS
906 __func_();
907 this->set_value();
908#ifndef _LIBCPP_NO_EXCEPTIONS
909 }
910 catch (...)
911 {
912 this->set_exception(current_exception());
913 }
914#endif // _LIBCPP_NO_EXCEPTIONS
915}
916
Howard Hinnantc834c512011-11-29 18:15:50 +0000917template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000918class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000919 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000920{
Howard Hinnantc834c512011-11-29 18:15:50 +0000921 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000922
Howard Hinnantc834c512011-11-29 18:15:50 +0000923 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000924
Howard Hinnant719bda32011-05-28 14:41:13 +0000925 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000926public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000927 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000928 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000929
930 virtual void __execute();
931};
932
Howard Hinnantc834c512011-11-29 18:15:50 +0000933template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000934inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000935__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
936 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000937{
938}
939
Howard Hinnantc834c512011-11-29 18:15:50 +0000940template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000941void
Howard Hinnantc834c512011-11-29 18:15:50 +0000942__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000943{
944#ifndef _LIBCPP_NO_EXCEPTIONS
945 try
946 {
947#endif // _LIBCPP_NO_EXCEPTIONS
948 this->set_value(__func_());
949#ifndef _LIBCPP_NO_EXCEPTIONS
950 }
951 catch (...)
952 {
953 this->set_exception(current_exception());
954 }
955#endif // _LIBCPP_NO_EXCEPTIONS
956}
957
Howard Hinnantc834c512011-11-29 18:15:50 +0000958template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000959void
Howard Hinnantc834c512011-11-29 18:15:50 +0000960__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000961{
962 this->wait();
963 base::__on_zero_shared();
964}
965
Howard Hinnantc834c512011-11-29 18:15:50 +0000966template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000967class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000968 : public __assoc_sub_state
969{
970 typedef __assoc_sub_state base;
971
Howard Hinnantc834c512011-11-29 18:15:50 +0000972 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000973
Howard Hinnant719bda32011-05-28 14:41:13 +0000974 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000975public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000976 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000977 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000978
979 virtual void __execute();
980};
981
Howard Hinnantc834c512011-11-29 18:15:50 +0000982template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000983inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000984__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
985 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000986{
987}
988
Howard Hinnantc834c512011-11-29 18:15:50 +0000989template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000990void
Howard Hinnantc834c512011-11-29 18:15:50 +0000991__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000992{
993#ifndef _LIBCPP_NO_EXCEPTIONS
994 try
995 {
996#endif // _LIBCPP_NO_EXCEPTIONS
997 __func_();
998 this->set_value();
999#ifndef _LIBCPP_NO_EXCEPTIONS
1000 }
1001 catch (...)
1002 {
1003 this->set_exception(current_exception());
1004 }
1005#endif // _LIBCPP_NO_EXCEPTIONS
1006}
1007
Howard Hinnantc834c512011-11-29 18:15:50 +00001008template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001009void
Howard Hinnantc834c512011-11-29 18:15:50 +00001010__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001011{
1012 this->wait();
1013 base::__on_zero_shared();
1014}
1015
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001016template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1017template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001018
1019// future
1020
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001021template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001022
Howard Hinnantc834c512011-11-29 18:15:50 +00001023template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001024_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001025__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001026
Howard Hinnantc834c512011-11-29 18:15:50 +00001027template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001028_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001029__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001030
Howard Hinnantc834c512011-11-29 18:15:50 +00001031template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001032class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001033{
Howard Hinnantc834c512011-11-29 18:15:50 +00001034 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001035
Howard Hinnantc834c512011-11-29 18:15:50 +00001036 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001037
1038 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001039 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001040
Howard Hinnantc834c512011-11-29 18:15:50 +00001041 template <class _R1, class _Fp>
1042 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1043 template <class _R1, class _Fp>
1044 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001045
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001046public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001048 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001049 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001050 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001051 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1052 future(const future&) = delete;
1053 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001055 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001056 {
1057 future(std::move(__rhs)).swap(*this);
1058 return *this;
1059 }
Louis Dionne7b844362020-07-30 09:42:23 -04001060
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001061 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001062 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001063 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001064
1065 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001066 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001067
Howard Hinnant684902d2010-09-22 14:16:26 +00001068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001069 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001070
1071 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001072 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001073 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001074
Howard Hinnant684902d2010-09-22 14:16:26 +00001075 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001076 void wait() const {__state_->wait();}
1077 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001078 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001079 future_status
1080 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1081 {return __state_->wait_for(__rel_time);}
1082 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001083 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001084 future_status
1085 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1086 {return __state_->wait_until(__abs_time);}
1087};
1088
Howard Hinnantc834c512011-11-29 18:15:50 +00001089template <class _Rp>
1090future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001091 : __state_(__state)
1092{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001093 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001094}
1095
Howard Hinnantccdd2032010-08-30 18:46:21 +00001096struct __release_shared_count
1097{
1098 void operator()(__shared_count* p) {p->__release_shared();}
1099};
1100
Howard Hinnantc834c512011-11-29 18:15:50 +00001101template <class _Rp>
1102future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001103{
1104 if (__state_)
1105 __state_->__release_shared();
1106}
1107
Howard Hinnantc834c512011-11-29 18:15:50 +00001108template <class _Rp>
1109_Rp
1110future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001111{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001112 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001113 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001114 __state_ = nullptr;
1115 return __s->move();
1116}
1117
Howard Hinnantc834c512011-11-29 18:15:50 +00001118template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001119class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001120{
Howard Hinnantc834c512011-11-29 18:15:50 +00001121 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001122
Howard Hinnantc834c512011-11-29 18:15:50 +00001123 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001124
1125 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001126 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001127
Howard Hinnantc834c512011-11-29 18:15:50 +00001128 template <class _R1, class _Fp>
1129 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1130 template <class _R1, class _Fp>
1131 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001132
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001133public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001134 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001135 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001137 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001138 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1139 future(const future&) = delete;
1140 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001142 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001143 {
1144 future(std::move(__rhs)).swap(*this);
1145 return *this;
1146 }
Louis Dionne7b844362020-07-30 09:42:23 -04001147
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001148 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001149 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001150 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001151
1152 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001153 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001154
Howard Hinnant684902d2010-09-22 14:16:26 +00001155 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001156 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001157
1158 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001159 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001160 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001161
Howard Hinnant684902d2010-09-22 14:16:26 +00001162 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001163 void wait() const {__state_->wait();}
1164 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001165 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001166 future_status
1167 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1168 {return __state_->wait_for(__rel_time);}
1169 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001170 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001171 future_status
1172 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1173 {return __state_->wait_until(__abs_time);}
1174};
1175
Howard Hinnantc834c512011-11-29 18:15:50 +00001176template <class _Rp>
1177future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001178 : __state_(__state)
1179{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001180 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001181}
1182
Howard Hinnantc834c512011-11-29 18:15:50 +00001183template <class _Rp>
1184future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001185{
1186 if (__state_)
1187 __state_->__release_shared();
1188}
1189
Howard Hinnantc834c512011-11-29 18:15:50 +00001190template <class _Rp>
1191_Rp&
1192future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001193{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001194 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001195 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001196 __state_ = nullptr;
1197 return __s->copy();
1198}
1199
1200template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001201class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001202{
1203 __assoc_sub_state* __state_;
1204
1205 explicit future(__assoc_sub_state* __state);
1206
1207 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001208 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001209
Howard Hinnantc834c512011-11-29 18:15:50 +00001210 template <class _R1, class _Fp>
1211 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1212 template <class _R1, class _Fp>
1213 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001214
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001215public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001216 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001217 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001218 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001219 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001220 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1221 future(const future&) = delete;
1222 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001223 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001224 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001225 {
1226 future(std::move(__rhs)).swap(*this);
1227 return *this;
1228 }
Louis Dionne7b844362020-07-30 09:42:23 -04001229
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001230 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001231 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001232 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001233
1234 // retrieving the value
1235 void get();
1236
Howard Hinnant684902d2010-09-22 14:16:26 +00001237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001238 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001239
1240 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001241 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001242 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001243
Howard Hinnant684902d2010-09-22 14:16:26 +00001244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001245 void wait() const {__state_->wait();}
1246 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001248 future_status
1249 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1250 {return __state_->wait_for(__rel_time);}
1251 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001252 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001253 future_status
1254 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1255 {return __state_->wait_until(__abs_time);}
1256};
1257
Howard Hinnantc834c512011-11-29 18:15:50 +00001258template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001259inline _LIBCPP_INLINE_VISIBILITY
1260void
Howard Hinnant22448042012-07-21 17:46:55 +00001261swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001262{
1263 __x.swap(__y);
1264}
1265
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001266// promise<R>
1267
Howard Hinnant944510a2011-06-14 19:58:17 +00001268template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001269
Howard Hinnantc834c512011-11-29 18:15:50 +00001270template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001271class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001272{
Howard Hinnantc834c512011-11-29 18:15:50 +00001273 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001274
Howard Hinnant684902d2010-09-22 14:16:26 +00001275 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001276 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001277
1278 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001279public:
1280 promise();
1281 template <class _Alloc>
1282 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001284 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001285 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1286 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001287 ~promise();
1288
1289 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001290 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001291 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001292 {
1293 promise(std::move(__rhs)).swap(*this);
1294 return *this;
1295 }
1296 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001297
Howard Hinnant684902d2010-09-22 14:16:26 +00001298 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001299 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001300
1301 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001302 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001303
1304 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001305 void set_value(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001306 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001307 void set_exception(exception_ptr __p);
1308
1309 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001310 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001311 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001312 void set_exception_at_thread_exit(exception_ptr __p);
1313};
1314
Howard Hinnantc834c512011-11-29 18:15:50 +00001315template <class _Rp>
1316promise<_Rp>::promise()
1317 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001318{
1319}
1320
Howard Hinnantc834c512011-11-29 18:15:50 +00001321template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001322template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001323promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001324{
Eric Fiselier0d109272014-10-23 06:24:45 +00001325 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1326 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001327 typedef __allocator_destructor<_A2> _D2;
1328 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001329 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1330 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1331 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001332}
1333
Howard Hinnantc834c512011-11-29 18:15:50 +00001334template <class _Rp>
1335promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001336{
1337 if (__state_)
1338 {
1339 if (!__state_->__has_value() && __state_->use_count() > 1)
1340 __state_->set_exception(make_exception_ptr(
1341 future_error(make_error_code(future_errc::broken_promise))
1342 ));
1343 __state_->__release_shared();
1344 }
1345}
1346
Howard Hinnantc834c512011-11-29 18:15:50 +00001347template <class _Rp>
1348future<_Rp>
1349promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001350{
1351 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001352 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001353 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001354}
1355
Howard Hinnantc834c512011-11-29 18:15:50 +00001356template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001357void
Howard Hinnantc834c512011-11-29 18:15:50 +00001358promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001359{
1360 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001361 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001362 __state_->set_value(__r);
1363}
1364
Howard Hinnantc834c512011-11-29 18:15:50 +00001365template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001366void
Howard Hinnantc834c512011-11-29 18:15:50 +00001367promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001368{
1369 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001370 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001371 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001372}
1373
Howard Hinnantc834c512011-11-29 18:15:50 +00001374template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001375void
Howard Hinnantc834c512011-11-29 18:15:50 +00001376promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001377{
Marshall Clow2b36f572016-05-16 16:55:32 +00001378 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001379 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001380 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001381 __state_->set_exception(__p);
1382}
1383
Howard Hinnantc834c512011-11-29 18:15:50 +00001384template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001385void
Howard Hinnantc834c512011-11-29 18:15:50 +00001386promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001387{
1388 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001389 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001390 __state_->set_value_at_thread_exit(__r);
1391}
1392
Howard Hinnantc834c512011-11-29 18:15:50 +00001393template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001394void
Howard Hinnantc834c512011-11-29 18:15:50 +00001395promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001396{
1397 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001398 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001399 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001400}
1401
Howard Hinnantc834c512011-11-29 18:15:50 +00001402template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001403void
Howard Hinnantc834c512011-11-29 18:15:50 +00001404promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001405{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001406 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001407 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001408 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001409 __state_->set_exception_at_thread_exit(__p);
1410}
1411
1412// promise<R&>
1413
Howard Hinnantc834c512011-11-29 18:15:50 +00001414template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001415class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001416{
Howard Hinnantc834c512011-11-29 18:15:50 +00001417 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001418
Howard Hinnant684902d2010-09-22 14:16:26 +00001419 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001420 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001421
1422 template <class> friend class packaged_task;
1423
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001424public:
1425 promise();
1426 template <class _Allocator>
1427 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001428 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001429 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001430 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1431 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001432 ~promise();
1433
1434 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001436 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001437 {
1438 promise(std::move(__rhs)).swap(*this);
1439 return *this;
1440 }
1441 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001442
Howard Hinnant684902d2010-09-22 14:16:26 +00001443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001444 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001445
1446 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001447 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001448
1449 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001450 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001451 void set_exception(exception_ptr __p);
1452
1453 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001454 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001455 void set_exception_at_thread_exit(exception_ptr __p);
1456};
1457
Howard Hinnantc834c512011-11-29 18:15:50 +00001458template <class _Rp>
1459promise<_Rp&>::promise()
1460 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001461{
1462}
1463
Howard Hinnantc834c512011-11-29 18:15:50 +00001464template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001465template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001466promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001467{
Eric Fiselier0d109272014-10-23 06:24:45 +00001468 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1469 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001470 typedef __allocator_destructor<_A2> _D2;
1471 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001472 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1473 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1474 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001475}
1476
Howard Hinnantc834c512011-11-29 18:15:50 +00001477template <class _Rp>
1478promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001479{
1480 if (__state_)
1481 {
1482 if (!__state_->__has_value() && __state_->use_count() > 1)
1483 __state_->set_exception(make_exception_ptr(
1484 future_error(make_error_code(future_errc::broken_promise))
1485 ));
1486 __state_->__release_shared();
1487 }
1488}
1489
Howard Hinnantc834c512011-11-29 18:15:50 +00001490template <class _Rp>
1491future<_Rp&>
1492promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001493{
1494 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001495 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001496 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001497}
1498
Howard Hinnantc834c512011-11-29 18:15:50 +00001499template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001500void
Howard Hinnantc834c512011-11-29 18:15:50 +00001501promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001502{
1503 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001504 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001505 __state_->set_value(__r);
1506}
1507
Howard Hinnantc834c512011-11-29 18:15:50 +00001508template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001509void
Howard Hinnantc834c512011-11-29 18:15:50 +00001510promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001511{
Marshall Clow2b36f572016-05-16 16:55:32 +00001512 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001513 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001514 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001515 __state_->set_exception(__p);
1516}
1517
Howard Hinnantc834c512011-11-29 18:15:50 +00001518template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001519void
Howard Hinnantc834c512011-11-29 18:15:50 +00001520promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001521{
1522 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001523 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001524 __state_->set_value_at_thread_exit(__r);
1525}
1526
Howard Hinnantc834c512011-11-29 18:15:50 +00001527template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001528void
Howard Hinnantc834c512011-11-29 18:15:50 +00001529promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001530{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001531 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001532 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001533 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001534 __state_->set_exception_at_thread_exit(__p);
1535}
1536
1537// promise<void>
1538
1539template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001540class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001541{
1542 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001543
Howard Hinnant684902d2010-09-22 14:16:26 +00001544 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001545 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001546
1547 template <class> friend class packaged_task;
1548
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001549public:
1550 promise();
1551 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001552 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001553 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001555 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001556 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1557 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001558 ~promise();
1559
1560 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001562 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001563 {
1564 promise(std::move(__rhs)).swap(*this);
1565 return *this;
1566 }
1567 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001568
Howard Hinnant684902d2010-09-22 14:16:26 +00001569 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001570 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001571
1572 // retrieving the result
1573 future<void> get_future();
1574
1575 // setting the result
1576 void set_value();
1577 void set_exception(exception_ptr __p);
1578
1579 // setting the result with deferred notification
1580 void set_value_at_thread_exit();
1581 void set_exception_at_thread_exit(exception_ptr __p);
1582};
1583
1584template <class _Alloc>
1585promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1586{
Eric Fiselier0d109272014-10-23 06:24:45 +00001587 typedef __assoc_sub_state_alloc<_Alloc> _State;
1588 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001589 typedef __allocator_destructor<_A2> _D2;
1590 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001591 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1592 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1593 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001594}
1595
Howard Hinnantc834c512011-11-29 18:15:50 +00001596template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001597inline _LIBCPP_INLINE_VISIBILITY
1598void
Howard Hinnant22448042012-07-21 17:46:55 +00001599swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001600{
1601 __x.swap(__y);
1602}
1603
Howard Hinnantc834c512011-11-29 18:15:50 +00001604template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001605 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001606 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001607
Howard Hinnantccdd2032010-08-30 18:46:21 +00001608#ifndef _LIBCPP_HAS_NO_VARIADICS
1609
1610// packaged_task
1611
1612template<class _Fp> class __packaged_task_base;
1613
Howard Hinnantc834c512011-11-29 18:15:50 +00001614template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001615class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001616{
1617 __packaged_task_base(const __packaged_task_base&);
1618 __packaged_task_base& operator=(const __packaged_task_base&);
1619public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001620 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001621 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001623 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001624 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001625 virtual void destroy() = 0;
1626 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001627 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001628};
1629
1630template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1631
Howard Hinnantc834c512011-11-29 18:15:50 +00001632template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001633class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001634 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001635{
Howard Hinnantc834c512011-11-29 18:15:50 +00001636 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001637public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001638 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001639 explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001640 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001641 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001642 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001643 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001644 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001645 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001646 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001647 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001648 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001649 virtual void destroy();
1650 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001651 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001652};
1653
Howard Hinnantc834c512011-11-29 18:15:50 +00001654template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001655void
Howard Hinnantc834c512011-11-29 18:15:50 +00001656__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001657 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001658{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001659 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001660}
1661
Howard Hinnantc834c512011-11-29 18:15:50 +00001662template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001663void
Howard Hinnantc834c512011-11-29 18:15:50 +00001664__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001665{
Howard Hinnantc834c512011-11-29 18:15:50 +00001666 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001667}
1668
Howard Hinnantc834c512011-11-29 18:15:50 +00001669template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001670void
Howard Hinnantc834c512011-11-29 18:15:50 +00001671__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001672{
Eric Fiselier0d109272014-10-23 06:24:45 +00001673 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1674 typedef allocator_traits<_Ap> _ATraits;
1675 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001676 _Ap __a(__f_.second());
1677 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001678 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001679}
1680
Howard Hinnantc834c512011-11-29 18:15:50 +00001681template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1682_Rp
1683__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001684{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001685 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001686}
1687
Howard Hinnant944510a2011-06-14 19:58:17 +00001688template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001689
Howard Hinnantc834c512011-11-29 18:15:50 +00001690template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001691class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001692{
Howard Hinnantc834c512011-11-29 18:15:50 +00001693 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001694
1695 _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
1696 __base* __get_buf() { return (__base*)&__buf_; }
1697
Howard Hinnant022c7482013-01-21 17:26:55 +00001698 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001699 __base* __f_;
1700
1701public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001702 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001703
1704 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001705 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001706 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001707 template<class _Fp>
1708 __packaged_task_function(_Fp&& __f);
1709 template<class _Fp, class _Alloc>
1710 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001711
Howard Hinnant22448042012-07-21 17:46:55 +00001712 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1713 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001714
1715 __packaged_task_function(const __packaged_task_function&) = delete;
1716 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1717
1718 ~__packaged_task_function();
1719
Howard Hinnant22448042012-07-21 17:46:55 +00001720 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001721
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001723 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001724};
1725
Howard Hinnantc834c512011-11-29 18:15:50 +00001726template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001727__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001728{
1729 if (__f.__f_ == nullptr)
1730 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001731 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001732 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001733 __f.__f_->__move_to(__get_buf());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001734 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001735 }
1736 else
1737 {
1738 __f_ = __f.__f_;
1739 __f.__f_ = nullptr;
1740 }
1741}
1742
Howard Hinnantc834c512011-11-29 18:15:50 +00001743template<class _Rp, class ..._ArgTypes>
1744template <class _Fp>
1745__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001746 : __f_(nullptr)
1747{
Marshall Clow733d60e2014-04-07 13:32:26 +00001748 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001749 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001750 if (sizeof(_FF) <= sizeof(__buf_))
1751 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001752 ::new (&__buf_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001753 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001754 }
1755 else
1756 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001757 typedef allocator<_FF> _Ap;
1758 _Ap __a;
1759 typedef __allocator_destructor<_Ap> _Dp;
1760 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1761 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001762 __f_ = __hold.release();
1763 }
1764}
1765
Howard Hinnantc834c512011-11-29 18:15:50 +00001766template<class _Rp, class ..._ArgTypes>
1767template <class _Fp, class _Alloc>
1768__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1769 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001770 : __f_(nullptr)
1771{
Marshall Clow733d60e2014-04-07 13:32:26 +00001772 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001773 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001774 if (sizeof(_FF) <= sizeof(__buf_))
1775 {
1776 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001777 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001778 }
1779 else
1780 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001781 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001782 _Ap __a(__a0);
1783 typedef __allocator_destructor<_Ap> _Dp;
1784 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001785 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1786 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1787 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001788 }
1789}
1790
Howard Hinnantc834c512011-11-29 18:15:50 +00001791template<class _Rp, class ..._ArgTypes>
1792__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001793__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001794{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001795 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001796 __f_->destroy();
1797 else if (__f_)
1798 __f_->destroy_deallocate();
1799 __f_ = nullptr;
1800 if (__f.__f_ == nullptr)
1801 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001802 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001803 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001804 __f.__f_->__move_to(__get_buf());
1805 __f_ = __get_buf();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001806 }
1807 else
1808 {
1809 __f_ = __f.__f_;
1810 __f.__f_ = nullptr;
1811 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001812 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001813}
1814
Howard Hinnantc834c512011-11-29 18:15:50 +00001815template<class _Rp, class ..._ArgTypes>
1816__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001817{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001818 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001819 __f_->destroy();
1820 else if (__f_)
1821 __f_->destroy_deallocate();
1822}
1823
Howard Hinnantc834c512011-11-29 18:15:50 +00001824template<class _Rp, class ..._ArgTypes>
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001825_LIBCPP_NO_CFI
Howard Hinnantccdd2032010-08-30 18:46:21 +00001826void
Howard Hinnant22448042012-07-21 17:46:55 +00001827__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001828{
1829 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1830 {
1831 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1832 __base* __t = (__base*)&__tempbuf;
1833 __f_->__move_to(__t);
1834 __f_->destroy();
1835 __f_ = nullptr;
1836 __f.__f_->__move_to((__base*)&__buf_);
1837 __f.__f_->destroy();
1838 __f.__f_ = nullptr;
1839 __f_ = (__base*)&__buf_;
1840 __t->__move_to((__base*)&__f.__buf_);
1841 __t->destroy();
1842 __f.__f_ = (__base*)&__f.__buf_;
1843 }
1844 else if (__f_ == (__base*)&__buf_)
1845 {
1846 __f_->__move_to((__base*)&__f.__buf_);
1847 __f_->destroy();
1848 __f_ = __f.__f_;
1849 __f.__f_ = (__base*)&__f.__buf_;
1850 }
1851 else if (__f.__f_ == (__base*)&__f.__buf_)
1852 {
1853 __f.__f_->__move_to((__base*)&__buf_);
1854 __f.__f_->destroy();
1855 __f.__f_ = __f_;
1856 __f_ = (__base*)&__buf_;
1857 }
1858 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001859 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001860}
1861
Howard Hinnantc834c512011-11-29 18:15:50 +00001862template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001863inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001864_Rp
1865__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001866{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001867 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001868}
1869
Howard Hinnantc834c512011-11-29 18:15:50 +00001870template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001871class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001872{
1873public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00001874 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00001875
1876private:
1877 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1878 promise<result_type> __p_;
1879
1880public:
1881 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00001882 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001883 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00001884 template <class _Fp,
1885 class = typename enable_if
1886 <
1887 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001888 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00001889 packaged_task
1890 >::value
1891 >::type
1892 >
Howard Hinnant684902d2010-09-22 14:16:26 +00001893 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001894 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00001895 template <class _Fp, class _Allocator,
1896 class = typename enable_if
1897 <
1898 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001899 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00001900 packaged_task
1901 >::value
1902 >::type
1903 >
1904 _LIBCPP_INLINE_VISIBILITY
1905 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1906 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1907 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001908 // ~packaged_task() = default;
1909
1910 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00001911 packaged_task(const packaged_task&) = delete;
1912 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001913
1914 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00001915 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001916 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001917 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001918 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001919 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001920 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001921 __f_ = _VSTD::move(__other.__f_);
1922 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001923 return *this;
1924 }
Howard Hinnant684902d2010-09-22 14:16:26 +00001925 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001926 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001927 {
1928 __f_.swap(__other.__f_);
1929 __p_.swap(__other.__p_);
1930 }
1931
Howard Hinnant684902d2010-09-22 14:16:26 +00001932 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001933 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001934
1935 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00001936 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001937 future<result_type> get_future() {return __p_.get_future();}
1938
1939 // execution
1940 void operator()(_ArgTypes... __args);
1941 void make_ready_at_thread_exit(_ArgTypes... __args);
1942
1943 void reset();
1944};
1945
Howard Hinnantc834c512011-11-29 18:15:50 +00001946template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001947void
Howard Hinnantc834c512011-11-29 18:15:50 +00001948packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001949{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001950 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001951 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001952 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001953 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001954#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001955 try
1956 {
1957#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001958 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001959#ifndef _LIBCPP_NO_EXCEPTIONS
1960 }
1961 catch (...)
1962 {
1963 __p_.set_exception(current_exception());
1964 }
1965#endif // _LIBCPP_NO_EXCEPTIONS
1966}
1967
Howard Hinnantc834c512011-11-29 18:15:50 +00001968template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001969void
Howard Hinnantc834c512011-11-29 18:15:50 +00001970packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001971{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001972 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001973 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001974 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001975 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001976#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001977 try
1978 {
1979#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001980 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001981#ifndef _LIBCPP_NO_EXCEPTIONS
1982 }
1983 catch (...)
1984 {
1985 __p_.set_exception_at_thread_exit(current_exception());
1986 }
1987#endif // _LIBCPP_NO_EXCEPTIONS
1988}
1989
Howard Hinnantc834c512011-11-29 18:15:50 +00001990template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001991void
Howard Hinnantc834c512011-11-29 18:15:50 +00001992packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001993{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001994 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00001995 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001996 __p_ = promise<result_type>();
1997}
1998
1999template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002000class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002001{
2002public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002003 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004
2005private:
2006 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2007 promise<result_type> __p_;
2008
2009public:
2010 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002012 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002013 template <class _Fp,
2014 class = typename enable_if
2015 <
2016 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002017 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002018 packaged_task
2019 >::value
2020 >::type
2021 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002022 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002023 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002024 template <class _Fp, class _Allocator,
2025 class = typename enable_if
2026 <
2027 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002028 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002029 packaged_task
2030 >::value
2031 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002032 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002033 _LIBCPP_INLINE_VISIBILITY
2034 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2035 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2036 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002037 // ~packaged_task() = default;
2038
2039 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002040 packaged_task(const packaged_task&) = delete;
2041 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002042
2043 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002045 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002046 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002048 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002049 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002050 __f_ = _VSTD::move(__other.__f_);
2051 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002052 return *this;
2053 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002055 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002056 {
2057 __f_.swap(__other.__f_);
2058 __p_.swap(__other.__p_);
2059 }
2060
Howard Hinnant684902d2010-09-22 14:16:26 +00002061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002062 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002063
2064 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002066 future<result_type> get_future() {return __p_.get_future();}
2067
2068 // execution
2069 void operator()(_ArgTypes... __args);
2070 void make_ready_at_thread_exit(_ArgTypes... __args);
2071
2072 void reset();
2073};
2074
2075template<class ..._ArgTypes>
2076void
2077packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2078{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002079 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002080 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002082 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002083#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002084 try
2085 {
2086#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002087 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002088 __p_.set_value();
2089#ifndef _LIBCPP_NO_EXCEPTIONS
2090 }
2091 catch (...)
2092 {
2093 __p_.set_exception(current_exception());
2094 }
2095#endif // _LIBCPP_NO_EXCEPTIONS
2096}
2097
2098template<class ..._ArgTypes>
2099void
2100packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2101{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002102 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002103 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002104 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002105 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002106#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002107 try
2108 {
2109#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002110 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002111 __p_.set_value_at_thread_exit();
2112#ifndef _LIBCPP_NO_EXCEPTIONS
2113 }
2114 catch (...)
2115 {
2116 __p_.set_exception_at_thread_exit(current_exception());
2117 }
2118#endif // _LIBCPP_NO_EXCEPTIONS
2119}
2120
2121template<class ..._ArgTypes>
2122void
2123packaged_task<void(_ArgTypes...)>::reset()
2124{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002125 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002126 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002127 __p_ = promise<result_type>();
2128}
2129
2130template <class _Callable>
2131inline _LIBCPP_INLINE_VISIBILITY
2132void
Howard Hinnant22448042012-07-21 17:46:55 +00002133swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002134{
2135 __x.swap(__y);
2136}
2137
Marshall Clowa0a057e2017-11-27 20:47:54 +00002138template <class _Callable, class _Alloc>
2139struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2140 : public true_type {};
2141
Howard Hinnantc834c512011-11-29 18:15:50 +00002142template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002143_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002144__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002145{
Howard Hinnantc834c512011-11-29 18:15:50 +00002146 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2147 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2148 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002149}
2150
Howard Hinnantc834c512011-11-29 18:15:50 +00002151template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002152_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002153__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002154{
Howard Hinnantc834c512011-11-29 18:15:50 +00002155 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2156 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2157 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2158 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002159}
2160
Howard Hinnantc834c512011-11-29 18:15:50 +00002161template <class _Fp, class... _Args>
Louis Dionne3b967d02019-12-10 18:00:42 -05002162class _LIBCPP_HIDDEN __async_func
Howard Hinnant95cfd872011-05-19 15:05:04 +00002163{
Howard Hinnantc834c512011-11-29 18:15:50 +00002164 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002165
2166public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002167 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002168
2169 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002170 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002171 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002172
2173 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002174 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002175
Howard Hinnantc834c512011-11-29 18:15:50 +00002176 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002177 {
2178 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2179 return __execute(_Index());
2180 }
2181private:
2182 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002183 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002184 __execute(__tuple_indices<_Indices...>)
2185 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002186 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002187 }
2188};
2189
Marshall Clowd56a5b62013-11-03 22:06:53 +00002190inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002191{ return (int(__policy) & int(__value)) != 0; }
2192
Howard Hinnantc834c512011-11-29 18:15:50 +00002193template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002194_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002195future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2196async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002197{
Howard Hinnantc834c512011-11-29 18:15:50 +00002198 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2199 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002200
2201#ifndef _LIBCPP_NO_EXCEPTIONS
2202 try
2203 {
2204#endif
2205 if (__does_policy_contain(__policy, launch::async))
2206 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002207 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002208#ifndef _LIBCPP_NO_EXCEPTIONS
2209 }
2210 catch ( ... ) { if (__policy == launch::async) throw ; }
2211#endif
2212
2213 if (__does_policy_contain(__policy, launch::deferred))
2214 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002215 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002216 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002217}
2218
Howard Hinnantc834c512011-11-29 18:15:50 +00002219template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002220_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002221future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2222async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002223{
Howard Hinnantc834c512011-11-29 18:15:50 +00002224 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002225 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002226}
2227
2228#endif // _LIBCPP_HAS_NO_VARIADICS
2229
Howard Hinnante6a10852010-09-03 21:46:37 +00002230// shared_future
2231
Howard Hinnantc834c512011-11-29 18:15:50 +00002232template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002233class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002234{
Howard Hinnantc834c512011-11-29 18:15:50 +00002235 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002236
2237public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002238 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002239 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002240 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002241 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002242 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002243 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002244 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002245 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002246 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002247 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002248 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002249 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002250 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant684902d2010-09-22 14:16:26 +00002251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002252 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002253 {
2254 shared_future(std::move(__rhs)).swap(*this);
2255 return *this;
2256 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002257
2258 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002259 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002260 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002261
Howard Hinnant684902d2010-09-22 14:16:26 +00002262 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002263 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002264
2265 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002266 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002267 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002268
Howard Hinnant684902d2010-09-22 14:16:26 +00002269 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002270 void wait() const {__state_->wait();}
2271 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002272 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002273 future_status
2274 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2275 {return __state_->wait_for(__rel_time);}
2276 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002277 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002278 future_status
2279 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2280 {return __state_->wait_until(__abs_time);}
2281};
2282
Howard Hinnantc834c512011-11-29 18:15:50 +00002283template <class _Rp>
2284shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002285{
2286 if (__state_)
2287 __state_->__release_shared();
2288}
2289
Howard Hinnantc834c512011-11-29 18:15:50 +00002290template <class _Rp>
2291shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002292shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002293{
2294 if (__rhs.__state_)
2295 __rhs.__state_->__add_shared();
2296 if (__state_)
2297 __state_->__release_shared();
2298 __state_ = __rhs.__state_;
2299 return *this;
2300}
2301
Howard Hinnantc834c512011-11-29 18:15:50 +00002302template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002303class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002304{
Howard Hinnantc834c512011-11-29 18:15:50 +00002305 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002306
2307public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002309 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002311 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2312 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002314 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002315 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002316 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002317 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002318 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002319 ~shared_future();
2320 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002322 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002323 {
2324 shared_future(std::move(__rhs)).swap(*this);
2325 return *this;
2326 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002327
2328 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002330 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002331
Howard Hinnant684902d2010-09-22 14:16:26 +00002332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002333 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002334
2335 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002336 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002337 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002338
Howard Hinnant684902d2010-09-22 14:16:26 +00002339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002340 void wait() const {__state_->wait();}
2341 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002342 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002343 future_status
2344 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2345 {return __state_->wait_for(__rel_time);}
2346 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002347 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002348 future_status
2349 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2350 {return __state_->wait_until(__abs_time);}
2351};
2352
Howard Hinnantc834c512011-11-29 18:15:50 +00002353template <class _Rp>
2354shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002355{
2356 if (__state_)
2357 __state_->__release_shared();
2358}
2359
Howard Hinnantc834c512011-11-29 18:15:50 +00002360template <class _Rp>
2361shared_future<_Rp&>&
2362shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002363{
2364 if (__rhs.__state_)
2365 __rhs.__state_->__add_shared();
2366 if (__state_)
2367 __state_->__release_shared();
2368 __state_ = __rhs.__state_;
2369 return *this;
2370}
2371
2372template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002373class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002374{
2375 __assoc_sub_state* __state_;
2376
2377public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002378 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002379 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002381 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2382 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002384 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002385 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002386 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002387 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002388 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002389 ~shared_future();
2390 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002392 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002393 {
2394 shared_future(std::move(__rhs)).swap(*this);
2395 return *this;
2396 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002397
2398 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002400 void get() const {__state_->copy();}
2401
Howard Hinnant684902d2010-09-22 14:16:26 +00002402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002403 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002404
2405 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002406 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002407 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002408
Howard Hinnant684902d2010-09-22 14:16:26 +00002409 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002410 void wait() const {__state_->wait();}
2411 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002412 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002413 future_status
2414 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2415 {return __state_->wait_for(__rel_time);}
2416 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002418 future_status
2419 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2420 {return __state_->wait_until(__abs_time);}
2421};
2422
Howard Hinnantc834c512011-11-29 18:15:50 +00002423template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002424inline _LIBCPP_INLINE_VISIBILITY
2425void
Howard Hinnant22448042012-07-21 17:46:55 +00002426swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002427{
2428 __x.swap(__y);
2429}
2430
Howard Hinnantc834c512011-11-29 18:15:50 +00002431template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002432inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002433shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002434future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002435{
Howard Hinnantc834c512011-11-29 18:15:50 +00002436 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002437}
2438
Howard Hinnantc834c512011-11-29 18:15:50 +00002439template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002440inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002441shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002442future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002443{
Howard Hinnantc834c512011-11-29 18:15:50 +00002444 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002445}
2446
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002447inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002448shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002449future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002450{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002451 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002452}
2453
Howard Hinnantc51e1022010-05-11 19:42:16 +00002454_LIBCPP_END_NAMESPACE_STD
2455
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002456#endif // !_LIBCPP_HAS_NO_THREADS
2457
Howard Hinnantc51e1022010-05-11 19:42:16 +00002458#endif // _LIBCPP_FUTURE