blob: 99df8831a7784dc284625ebecb615923f66c5c45 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
Louis Dionne9bd93882021-11-17 16:25:01 -05002//===----------------------------------------------------------------------===//
Howard Hinnantc51e1022010-05-11 19:42:16 +00003//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUTURE
11#define _LIBCPP_FUTURE
12
13/*
14 future synopsis
15
16namespace std
17{
18
19enum class future_errc
20{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000021 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000022 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000023 no_state,
24 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000025};
26
27enum class launch
28{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000029 async = 1,
30 deferred = 2,
31 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000032};
33
34enum class future_status
35{
36 ready,
37 timeout,
38 deferred
39};
40
41template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000042error_code make_error_code(future_errc e) noexcept;
43error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000044
Howard Hinnant22448042012-07-21 17:46:55 +000045const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000046
47class future_error
48 : public logic_error
49{
50public:
51 future_error(error_code ec); // exposition only
Marshall Clowd4a669c2016-11-14 18:56:24 +000052 explicit future_error(future_errc); // C++17
Howard Hinnant22448042012-07-21 17:46:55 +000053 const error_code& code() const noexcept;
54 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000055};
56
57template <class R>
58class promise
59{
60public:
61 promise();
62 template <class Allocator>
63 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000064 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000065 promise(const promise& rhs) = delete;
66 ~promise();
67
68 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000069 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000070 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000071 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000072
73 // retrieving the result
74 future<R> get_future();
75
76 // setting the result
77 void set_value(const R& r);
78 void set_value(R&& r);
79 void set_exception(exception_ptr p);
80
81 // setting the result with deferred notification
82 void set_value_at_thread_exit(const R& r);
83 void set_value_at_thread_exit(R&& r);
84 void set_exception_at_thread_exit(exception_ptr p);
85};
86
87template <class R>
88class promise<R&>
89{
90public:
91 promise();
92 template <class Allocator>
93 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000094 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000095 promise(const promise& rhs) = delete;
96 ~promise();
97
98 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000099 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000100 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000101 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000102
103 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000104 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000105
106 // setting the result
107 void set_value(R& r);
108 void set_exception(exception_ptr p);
109
110 // setting the result with deferred notification
111 void set_value_at_thread_exit(R&);
112 void set_exception_at_thread_exit(exception_ptr p);
113};
114
115template <>
116class promise<void>
117{
118public:
119 promise();
120 template <class Allocator>
121 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000122 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000123 promise(const promise& rhs) = delete;
124 ~promise();
125
126 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000127 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000128 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000129 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000130
131 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000132 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000133
134 // setting the result
135 void set_value();
136 void set_exception(exception_ptr p);
137
138 // setting the result with deferred notification
139 void set_value_at_thread_exit();
140 void set_exception_at_thread_exit(exception_ptr p);
141};
142
Howard Hinnant22448042012-07-21 17:46:55 +0000143template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000144
145template <class R, class Alloc>
146 struct uses_allocator<promise<R>, Alloc> : public true_type {};
147
148template <class R>
149class future
150{
151public:
Howard Hinnant22448042012-07-21 17:46:55 +0000152 future() noexcept;
153 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000154 future(const future& rhs) = delete;
155 ~future();
156 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000157 future& operator=(future&&) noexcept;
Marshall Clow597881d2017-01-25 20:14:03 +0000158 shared_future<R> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000159
160 // retrieving the value
161 R get();
162
163 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000164 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000165
166 void wait() const;
167 template <class Rep, class Period>
168 future_status
169 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
170 template <class Clock, class Duration>
171 future_status
172 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
173};
174
175template <class R>
176class future<R&>
177{
178public:
Howard Hinnant22448042012-07-21 17:46:55 +0000179 future() noexcept;
180 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000181 future(const future& rhs) = delete;
182 ~future();
183 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000184 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000185 shared_future<R&> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000186
187 // retrieving the value
188 R& get();
189
190 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000191 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000192
193 void wait() const;
194 template <class Rep, class Period>
195 future_status
196 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
197 template <class Clock, class Duration>
198 future_status
199 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
200};
201
202template <>
203class future<void>
204{
205public:
Howard Hinnant22448042012-07-21 17:46:55 +0000206 future() noexcept;
207 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000208 future(const future& rhs) = delete;
209 ~future();
210 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000211 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000212 shared_future<void> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000213
214 // retrieving the value
215 void get();
216
217 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000218 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000219
220 void wait() const;
221 template <class Rep, class Period>
222 future_status
223 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
224 template <class Clock, class Duration>
225 future_status
226 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
227};
228
229template <class R>
230class shared_future
231{
232public:
Howard Hinnant22448042012-07-21 17:46:55 +0000233 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000234 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000235 shared_future(future<R>&&) noexcept;
236 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000237 ~shared_future();
238 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000239 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000240
241 // retrieving the value
242 const R& get() const;
243
244 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000245 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246
247 void wait() const;
248 template <class Rep, class Period>
249 future_status
250 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
251 template <class Clock, class Duration>
252 future_status
253 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
254};
255
256template <class R>
257class shared_future<R&>
258{
259public:
Howard Hinnant22448042012-07-21 17:46:55 +0000260 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000261 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000262 shared_future(future<R&>&&) noexcept;
263 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264 ~shared_future();
265 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000266 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000267
268 // retrieving the value
269 R& get() const;
270
271 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000272 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000273
274 void wait() const;
275 template <class Rep, class Period>
276 future_status
277 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
278 template <class Clock, class Duration>
279 future_status
280 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
281};
282
283template <>
284class shared_future<void>
285{
286public:
Howard Hinnant22448042012-07-21 17:46:55 +0000287 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000288 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000289 shared_future(future<void>&&) noexcept;
290 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000291 ~shared_future();
292 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000293 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000294
295 // retrieving the value
296 void get() const;
297
298 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000299 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000300
301 void wait() const;
302 template <class Rep, class Period>
303 future_status
304 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
305 template <class Clock, class Duration>
306 future_status
307 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
308};
309
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000311 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000312 async(F&& f, Args&&... args);
313
314template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000315 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000316 async(launch policy, F&& f, Args&&... args);
317
Howard Hinnantc566dc32010-05-11 21:36:01 +0000318template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000319
320template <class R, class... ArgTypes>
321class packaged_task<R(ArgTypes...)>
322{
323public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +0000324 typedef R result_type; // extension
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325
326 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000327 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000328 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 explicit packaged_task(F&& f);
Marshall Clowa0a057e2017-11-27 20:47:54 +0000330 template <class F, class Allocator>
331 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332 ~packaged_task();
333
334 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000335 packaged_task(const packaged_task&) = delete;
336 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337
338 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000339 packaged_task(packaged_task&& other) noexcept;
340 packaged_task& operator=(packaged_task&& other) noexcept;
341 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000342
Howard Hinnant22448042012-07-21 17:46:55 +0000343 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344
345 // result retrieval
346 future<R> get_future();
347
348 // execution
349 void operator()(ArgTypes... );
350 void make_ready_at_thread_exit(ArgTypes...);
351
352 void reset();
353};
354
355template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000356 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000357
Marshall Clowa0a057e2017-11-27 20:47:54 +0000358template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
359
Howard Hinnantc51e1022010-05-11 19:42:16 +0000360} // std
361
362*/
363
Louis Dionne73912b22020-11-04 15:01:25 -0500364#include <__availability>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400365#include <__config>
Arthur O'Dwyer597cac42021-05-12 23:04:03 -0400366#include <__debug>
Christopher Di Bella55d7a822021-07-01 09:25:35 -0400367#include <__memory/allocator_arg_t.h>
368#include <__memory/uses_allocator.h>
Louis Dionne64f0cbf2021-08-27 10:36:04 -0400369#include <__utility/decay_copy.h>
Christopher Di Bella41f26e82021-06-05 02:47:47 +0000370#include <__utility/forward.h>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000371#include <chrono>
372#include <exception>
Arthur O'Dwyer597cac42021-05-12 23:04:03 -0400373#include <memory>
Howard Hinnante6a10852010-09-03 21:46:37 +0000374#include <mutex>
Arthur O'Dwyer597cac42021-05-12 23:04:03 -0400375#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000376#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000377
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000378#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000379#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000380#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000381
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000382#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000383#error <future> is not supported on this single threaded system
384#else // !_LIBCPP_HAS_NO_THREADS
385
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386_LIBCPP_BEGIN_NAMESPACE_STD
387
388//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000389_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000391 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000392 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000393 no_state,
394 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000395};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000396_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000397
Howard Hinnant684902d2010-09-22 14:16:26 +0000398template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000399struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000400
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000401#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
402template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000403struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000404#endif
405
Howard Hinnantc51e1022010-05-11 19:42:16 +0000406//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000407_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000408{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000409 async = 1,
410 deferred = 2,
411 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000412};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000413_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000414
Howard Hinnantda760a82013-06-29 18:38:17 +0000415#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
416
Howard Hinnantda760a82013-06-29 18:38:17 +0000417typedef underlying_type<launch>::type __launch_underlying_type;
Howard Hinnantda760a82013-06-29 18:38:17 +0000418
419inline _LIBCPP_INLINE_VISIBILITY
420_LIBCPP_CONSTEXPR
421launch
422operator&(launch __x, launch __y)
423{
424 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
425 static_cast<__launch_underlying_type>(__y));
426}
427
428inline _LIBCPP_INLINE_VISIBILITY
429_LIBCPP_CONSTEXPR
430launch
431operator|(launch __x, launch __y)
432{
433 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
434 static_cast<__launch_underlying_type>(__y));
435}
436
437inline _LIBCPP_INLINE_VISIBILITY
438_LIBCPP_CONSTEXPR
439launch
440operator^(launch __x, launch __y)
441{
442 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
443 static_cast<__launch_underlying_type>(__y));
444}
445
446inline _LIBCPP_INLINE_VISIBILITY
447_LIBCPP_CONSTEXPR
448launch
449operator~(launch __x)
450{
Howard Hinnant373d7602013-07-02 18:01:41 +0000451 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000452}
453
454inline _LIBCPP_INLINE_VISIBILITY
455launch&
456operator&=(launch& __x, launch __y)
457{
458 __x = __x & __y; return __x;
459}
460
461inline _LIBCPP_INLINE_VISIBILITY
462launch&
463operator|=(launch& __x, launch __y)
464{
465 __x = __x | __y; return __x;
466}
467
468inline _LIBCPP_INLINE_VISIBILITY
469launch&
470operator^=(launch& __x, launch __y)
471{
472 __x = __x ^ __y; return __x;
473}
474
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400475#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
Howard Hinnantda760a82013-06-29 18:38:17 +0000476
Howard Hinnantc51e1022010-05-11 19:42:16 +0000477//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000478_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000480 ready,
481 timeout,
482 deferred
483};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000484_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000485
Howard Hinnant8331b762013-03-06 23:30:19 +0000486_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000487const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000488
489inline _LIBCPP_INLINE_VISIBILITY
490error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000491make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000492{
493 return error_code(static_cast<int>(__e), future_category());
494}
495
496inline _LIBCPP_INLINE_VISIBILITY
497error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000498make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000499{
500 return error_condition(static_cast<int>(__e), future_category());
501}
502
Mehdi Amini228053d2017-05-04 17:08:54 +0000503class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000504 : public logic_error
505{
506 error_code __ec_;
507public:
508 future_error(error_code __ec);
Marek Kurdejf3197922021-04-01 08:29:55 +0200509
Howard Hinnant684902d2010-09-22 14:16:26 +0000510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000511 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000512
Dimitry Andric47269ce2020-03-13 19:36:26 +0100513 future_error(const future_error&) _NOEXCEPT = default;
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000514 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000515};
516
Louis Dionne16fe2952018-07-11 23:14:33 +0000517_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000518#ifndef _LIBCPP_NO_EXCEPTIONS
519_LIBCPP_AVAILABILITY_FUTURE_ERROR
520#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000521void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000522{
523#ifndef _LIBCPP_NO_EXCEPTIONS
524 throw future_error(make_error_code(_Ev));
525#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000526 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000527 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000528#endif
529}
530
Mehdi Amini228053d2017-05-04 17:08:54 +0000531class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000532 : public __shared_count
533{
534protected:
535 exception_ptr __exception_;
536 mutable mutex __mut_;
537 mutable condition_variable __cv_;
538 unsigned __state_;
539
Howard Hinnant719bda32011-05-28 14:41:13 +0000540 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000541 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000542public:
543 enum
544 {
545 __constructed = 1,
546 __future_attached = 2,
547 ready = 4,
548 deferred = 8
549 };
550
Howard Hinnant684902d2010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000552 __assoc_sub_state() : __state_(0) {}
553
Howard Hinnant684902d2010-09-22 14:16:26 +0000554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000555 bool __has_value() const
556 {return (__state_ & __constructed) || (__exception_ != nullptr);}
557
Howard Hinnant684902d2010-09-22 14:16:26 +0000558 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000559 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000560 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000561 bool __has_future_attached = (__state_ & __future_attached) != 0;
562 if (__has_future_attached)
563 __throw_future_error(future_errc::future_already_retrieved);
564 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000565 __state_ |= __future_attached;
566 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567
Howard Hinnant684902d2010-09-22 14:16:26 +0000568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000569 void __set_deferred() {__state_ |= deferred;}
570
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000571 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000572 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000573 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000574
575 void set_value();
576 void set_value_at_thread_exit();
577
578 void set_exception(exception_ptr __p);
579 void set_exception_at_thread_exit(exception_ptr __p);
580
581 void copy();
582
Howard Hinnantccdd2032010-08-30 18:46:21 +0000583 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000584 template <class _Rep, class _Period>
585 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000587 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
588 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000589 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000590 future_status
591 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000592
593 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000594};
595
Howard Hinnantf4712b92010-08-28 21:01:06 +0000596template <class _Clock, class _Duration>
597future_status
598__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
599{
600 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000601 if (__state_ & deferred)
602 return future_status::deferred;
603 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000604 __cv_.wait_until(__lk, __abs_time);
605 if (__state_ & ready)
606 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000607 return future_status::timeout;
608}
609
610template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000611inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000612future_status
613__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
614{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000615 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000616}
617
Howard Hinnantc834c512011-11-29 18:15:50 +0000618template <class _Rp>
Louis Dionne3b967d02019-12-10 18:00:42 -0500619class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620 : public __assoc_sub_state
621{
622 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000623 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000624protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000625 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000626
Howard Hinnant719bda32011-05-28 14:41:13 +0000627 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000628public:
629
630 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400631 void set_value(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000632
633 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400634 void set_value_at_thread_exit(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000635
Howard Hinnantc834c512011-11-29 18:15:50 +0000636 _Rp move();
637 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000638};
639
Howard Hinnantc834c512011-11-29 18:15:50 +0000640template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000641void
Howard Hinnantc834c512011-11-29 18:15:50 +0000642__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000643{
644 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000645 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000646 delete this;
647}
648
Howard Hinnantc834c512011-11-29 18:15:50 +0000649template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000650template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000651_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000652void
Howard Hinnantc834c512011-11-29 18:15:50 +0000653__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000654{
655 unique_lock<mutex> __lk(this->__mut_);
656 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000657 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500658 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000659 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000660 __cv_.notify_all();
661}
662
Howard Hinnantc834c512011-11-29 18:15:50 +0000663template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000664template <class _Arg>
665void
Howard Hinnantc834c512011-11-29 18:15:50 +0000666__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000667{
668 unique_lock<mutex> __lk(this->__mut_);
669 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000670 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500671 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000672 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000673 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000674}
675
Howard Hinnantc834c512011-11-29 18:15:50 +0000676template <class _Rp>
677_Rp
678__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000679{
680 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000681 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000682 if (this->__exception_ != nullptr)
683 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000684 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000685}
686
Howard Hinnantc834c512011-11-29 18:15:50 +0000687template <class _Rp>
688typename add_lvalue_reference<_Rp>::type
689__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000690{
691 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000692 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000693 if (this->__exception_ != nullptr)
694 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000695 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000696}
697
Howard Hinnantc834c512011-11-29 18:15:50 +0000698template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000699class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000700 : public __assoc_sub_state
701{
702 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000703 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000704protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000705 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000706
Howard Hinnant719bda32011-05-28 14:41:13 +0000707 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000708public:
709
Howard Hinnantc834c512011-11-29 18:15:50 +0000710 void set_value(_Rp& __arg);
711 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000712
Howard Hinnantc834c512011-11-29 18:15:50 +0000713 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000714};
715
Howard Hinnantc834c512011-11-29 18:15:50 +0000716template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000717void
Howard Hinnantc834c512011-11-29 18:15:50 +0000718__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000719{
720 delete this;
721}
722
Howard Hinnantc834c512011-11-29 18:15:50 +0000723template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000724void
Howard Hinnantc834c512011-11-29 18:15:50 +0000725__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000726{
727 unique_lock<mutex> __lk(this->__mut_);
728 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000729 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000730 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000731 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000732 __cv_.notify_all();
733}
734
Howard Hinnantc834c512011-11-29 18:15:50 +0000735template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000736void
Howard Hinnantc834c512011-11-29 18:15:50 +0000737__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000738{
739 unique_lock<mutex> __lk(this->__mut_);
740 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000741 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000742 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000744 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000745}
746
Howard Hinnantc834c512011-11-29 18:15:50 +0000747template <class _Rp>
748_Rp&
749__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000750{
751 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000752 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000753 if (this->__exception_ != nullptr)
754 rethrow_exception(this->__exception_);
755 return *__value_;
756}
757
Howard Hinnantc834c512011-11-29 18:15:50 +0000758template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000759class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000760 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000761{
Howard Hinnantc834c512011-11-29 18:15:50 +0000762 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000763 _Alloc __alloc_;
764
Howard Hinnant719bda32011-05-28 14:41:13 +0000765 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000766public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000767 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000768 explicit __assoc_state_alloc(const _Alloc& __a)
769 : __alloc_(__a) {}
770};
771
Howard Hinnantc834c512011-11-29 18:15:50 +0000772template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000773void
Howard Hinnantc834c512011-11-29 18:15:50 +0000774__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000775{
776 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000777 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000778 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
779 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000780 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000781 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000782 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000783 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000784}
785
Howard Hinnantc834c512011-11-29 18:15:50 +0000786template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000787class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000788 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000789{
Howard Hinnantc834c512011-11-29 18:15:50 +0000790 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000791 _Alloc __alloc_;
792
Howard Hinnant719bda32011-05-28 14:41:13 +0000793 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000794public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000795 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000796 explicit __assoc_state_alloc(const _Alloc& __a)
797 : __alloc_(__a) {}
798};
799
Howard Hinnantc834c512011-11-29 18:15:50 +0000800template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000801void
Howard Hinnantc834c512011-11-29 18:15:50 +0000802__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000803{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000804 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
805 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000806 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000807 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000808 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000809 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000810}
811
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000812template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000813class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000814 : public __assoc_sub_state
815{
816 typedef __assoc_sub_state base;
817 _Alloc __alloc_;
818
Howard Hinnant719bda32011-05-28 14:41:13 +0000819 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000820public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000821 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000822 explicit __assoc_sub_state_alloc(const _Alloc& __a)
823 : __alloc_(__a) {}
824};
825
826template <class _Alloc>
827void
Howard Hinnant719bda32011-05-28 14:41:13 +0000828__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000829{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000830 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
831 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000832 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000833 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000834 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000835 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000836}
837
Howard Hinnantc834c512011-11-29 18:15:50 +0000838template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000839class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000840 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000841{
Howard Hinnantc834c512011-11-29 18:15:50 +0000842 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000843
Howard Hinnantc834c512011-11-29 18:15:50 +0000844 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000845
846public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000847 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000848 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000849
850 virtual void __execute();
851};
852
Howard Hinnantc834c512011-11-29 18:15:50 +0000853template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000854inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000855__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
856 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000857{
858 this->__set_deferred();
859}
860
Howard Hinnantc834c512011-11-29 18:15:50 +0000861template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000862void
Howard Hinnantc834c512011-11-29 18:15:50 +0000863__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000864{
865#ifndef _LIBCPP_NO_EXCEPTIONS
866 try
867 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400868#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000869 this->set_value(__func_());
870#ifndef _LIBCPP_NO_EXCEPTIONS
871 }
872 catch (...)
873 {
874 this->set_exception(current_exception());
875 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400876#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000877}
878
Howard Hinnantc834c512011-11-29 18:15:50 +0000879template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000880class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000881 : public __assoc_sub_state
882{
883 typedef __assoc_sub_state base;
884
Howard Hinnantc834c512011-11-29 18:15:50 +0000885 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000886
887public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000888 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000889 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000890
891 virtual void __execute();
892};
893
Howard Hinnantc834c512011-11-29 18:15:50 +0000894template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000895inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000896__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
897 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000898{
899 this->__set_deferred();
900}
901
Howard Hinnantc834c512011-11-29 18:15:50 +0000902template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000903void
Howard Hinnantc834c512011-11-29 18:15:50 +0000904__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000905{
906#ifndef _LIBCPP_NO_EXCEPTIONS
907 try
908 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400909#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000910 __func_();
911 this->set_value();
912#ifndef _LIBCPP_NO_EXCEPTIONS
913 }
914 catch (...)
915 {
916 this->set_exception(current_exception());
917 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400918#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000919}
920
Howard Hinnantc834c512011-11-29 18:15:50 +0000921template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000922class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000923 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000924{
Howard Hinnantc834c512011-11-29 18:15:50 +0000925 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000926
Howard Hinnantc834c512011-11-29 18:15:50 +0000927 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000928
Howard Hinnant719bda32011-05-28 14:41:13 +0000929 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000930public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000931 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000932 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000933
934 virtual void __execute();
935};
936
Howard Hinnantc834c512011-11-29 18:15:50 +0000937template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000938inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000939__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
940 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000941{
942}
943
Howard Hinnantc834c512011-11-29 18:15:50 +0000944template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000945void
Howard Hinnantc834c512011-11-29 18:15:50 +0000946__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000947{
948#ifndef _LIBCPP_NO_EXCEPTIONS
949 try
950 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400951#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +0000952 this->set_value(__func_());
953#ifndef _LIBCPP_NO_EXCEPTIONS
954 }
955 catch (...)
956 {
957 this->set_exception(current_exception());
958 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400959#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +0000960}
961
Howard Hinnantc834c512011-11-29 18:15:50 +0000962template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000963void
Howard Hinnantc834c512011-11-29 18:15:50 +0000964__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000965{
966 this->wait();
967 base::__on_zero_shared();
968}
969
Howard Hinnantc834c512011-11-29 18:15:50 +0000970template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000971class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000972 : public __assoc_sub_state
973{
974 typedef __assoc_sub_state base;
975
Howard Hinnantc834c512011-11-29 18:15:50 +0000976 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000977
Howard Hinnant719bda32011-05-28 14:41:13 +0000978 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000979public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000980 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000981 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000982
983 virtual void __execute();
984};
985
Howard Hinnantc834c512011-11-29 18:15:50 +0000986template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000987inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000988__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
989 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000990{
991}
992
Howard Hinnantc834c512011-11-29 18:15:50 +0000993template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000994void
Howard Hinnantc834c512011-11-29 18:15:50 +0000995__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000996{
997#ifndef _LIBCPP_NO_EXCEPTIONS
998 try
999 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001000#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +00001001 __func_();
1002 this->set_value();
1003#ifndef _LIBCPP_NO_EXCEPTIONS
1004 }
1005 catch (...)
1006 {
1007 this->set_exception(current_exception());
1008 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001009#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +00001010}
1011
Howard Hinnantc834c512011-11-29 18:15:50 +00001012template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001013void
Howard Hinnantc834c512011-11-29 18:15:50 +00001014__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001015{
1016 this->wait();
1017 base::__on_zero_shared();
1018}
1019
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001020template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1021template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001022
1023// future
1024
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001025template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
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_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001030
Howard Hinnantc834c512011-11-29 18:15:50 +00001031template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001032_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001033__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001034
Howard Hinnantc834c512011-11-29 18:15:50 +00001035template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001036class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001037{
Howard Hinnantc834c512011-11-29 18:15:50 +00001038 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001039
Howard Hinnantc834c512011-11-29 18:15:50 +00001040 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001041
1042 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001043 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001044
Howard Hinnantc834c512011-11-29 18:15:50 +00001045 template <class _R1, class _Fp>
1046 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1047 template <class _R1, class _Fp>
1048 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001049
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001050public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001052 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001053 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001054 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001055 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1056 future(const future&) = delete;
1057 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001059 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001060 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001061 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001062 return *this;
1063 }
Louis Dionne7b844362020-07-30 09:42:23 -04001064
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001065 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001066 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001067 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001068
1069 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001070 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001071
Howard Hinnant684902d2010-09-22 14:16:26 +00001072 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001073 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001074
1075 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001077 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001078
Howard Hinnant684902d2010-09-22 14:16:26 +00001079 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001080 void wait() const {__state_->wait();}
1081 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001082 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001083 future_status
1084 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1085 {return __state_->wait_for(__rel_time);}
1086 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001087 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001088 future_status
1089 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1090 {return __state_->wait_until(__abs_time);}
1091};
1092
Howard Hinnantc834c512011-11-29 18:15:50 +00001093template <class _Rp>
1094future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001095 : __state_(__state)
1096{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001097 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001098}
1099
Howard Hinnantccdd2032010-08-30 18:46:21 +00001100struct __release_shared_count
1101{
1102 void operator()(__shared_count* p) {p->__release_shared();}
1103};
1104
Howard Hinnantc834c512011-11-29 18:15:50 +00001105template <class _Rp>
1106future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001107{
1108 if (__state_)
1109 __state_->__release_shared();
1110}
1111
Howard Hinnantc834c512011-11-29 18:15:50 +00001112template <class _Rp>
1113_Rp
1114future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001115{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001116 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001117 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001118 __state_ = nullptr;
1119 return __s->move();
1120}
1121
Howard Hinnantc834c512011-11-29 18:15:50 +00001122template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001123class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001124{
Howard Hinnantc834c512011-11-29 18:15:50 +00001125 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001126
Howard Hinnantc834c512011-11-29 18:15:50 +00001127 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001128
1129 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001130 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001131
Howard Hinnantc834c512011-11-29 18:15:50 +00001132 template <class _R1, class _Fp>
1133 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1134 template <class _R1, class _Fp>
1135 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001136
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001137public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001138 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001139 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001140 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001141 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001142 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1143 future(const future&) = delete;
1144 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001145 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001146 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001147 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001148 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001149 return *this;
1150 }
Louis Dionne7b844362020-07-30 09:42:23 -04001151
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001152 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001153 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001154 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001155
1156 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001157 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001158
Howard Hinnant684902d2010-09-22 14:16:26 +00001159 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001160 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001161
1162 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001163 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001164 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001165
Howard Hinnant684902d2010-09-22 14:16:26 +00001166 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001167 void wait() const {__state_->wait();}
1168 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001169 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001170 future_status
1171 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1172 {return __state_->wait_for(__rel_time);}
1173 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001174 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001175 future_status
1176 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1177 {return __state_->wait_until(__abs_time);}
1178};
1179
Howard Hinnantc834c512011-11-29 18:15:50 +00001180template <class _Rp>
1181future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001182 : __state_(__state)
1183{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001184 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001185}
1186
Howard Hinnantc834c512011-11-29 18:15:50 +00001187template <class _Rp>
1188future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001189{
1190 if (__state_)
1191 __state_->__release_shared();
1192}
1193
Howard Hinnantc834c512011-11-29 18:15:50 +00001194template <class _Rp>
1195_Rp&
1196future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001197{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001198 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001199 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001200 __state_ = nullptr;
1201 return __s->copy();
1202}
1203
1204template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001205class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001206{
1207 __assoc_sub_state* __state_;
1208
1209 explicit future(__assoc_sub_state* __state);
1210
1211 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001212 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001213
Howard Hinnantc834c512011-11-29 18:15:50 +00001214 template <class _R1, class _Fp>
1215 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1216 template <class _R1, class _Fp>
1217 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001218
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001219public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001220 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001221 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001222 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001223 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001224 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1225 future(const future&) = delete;
1226 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001227 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001228 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001229 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001230 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001231 return *this;
1232 }
Louis Dionne7b844362020-07-30 09:42:23 -04001233
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001234 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001235 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001236 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001237
1238 // retrieving the value
1239 void get();
1240
Howard Hinnant684902d2010-09-22 14:16:26 +00001241 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001242 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001243
1244 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001246 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001247
Howard Hinnant684902d2010-09-22 14:16:26 +00001248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001249 void wait() const {__state_->wait();}
1250 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001252 future_status
1253 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1254 {return __state_->wait_for(__rel_time);}
1255 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001257 future_status
1258 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1259 {return __state_->wait_until(__abs_time);}
1260};
1261
Howard Hinnantc834c512011-11-29 18:15:50 +00001262template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001263inline _LIBCPP_INLINE_VISIBILITY
1264void
Howard Hinnant22448042012-07-21 17:46:55 +00001265swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001266{
1267 __x.swap(__y);
1268}
1269
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001270// promise<R>
1271
Howard Hinnant944510a2011-06-14 19:58:17 +00001272template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001273
Howard Hinnantc834c512011-11-29 18:15:50 +00001274template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001275class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001276{
Howard Hinnantc834c512011-11-29 18:15:50 +00001277 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001278
Howard Hinnant684902d2010-09-22 14:16:26 +00001279 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001280 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001281
1282 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001283public:
1284 promise();
1285 template <class _Alloc>
1286 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001287 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001288 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001289 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1290 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001291 ~promise();
1292
1293 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001294 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001295 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001296 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001297 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001298 return *this;
1299 }
1300 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001301
Howard Hinnant684902d2010-09-22 14:16:26 +00001302 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001303 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001304
1305 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001306 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001307
1308 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001309 void set_value(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001310 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001311 void set_exception(exception_ptr __p);
1312
1313 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001314 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001315 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001316 void set_exception_at_thread_exit(exception_ptr __p);
1317};
1318
Howard Hinnantc834c512011-11-29 18:15:50 +00001319template <class _Rp>
1320promise<_Rp>::promise()
1321 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001322{
1323}
1324
Howard Hinnantc834c512011-11-29 18:15:50 +00001325template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001326template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001327promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001328{
Eric Fiselier0d109272014-10-23 06:24:45 +00001329 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1330 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001331 typedef __allocator_destructor<_A2> _D2;
1332 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001333 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001334 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001335 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001336}
1337
Howard Hinnantc834c512011-11-29 18:15:50 +00001338template <class _Rp>
1339promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001340{
1341 if (__state_)
1342 {
1343 if (!__state_->__has_value() && __state_->use_count() > 1)
1344 __state_->set_exception(make_exception_ptr(
1345 future_error(make_error_code(future_errc::broken_promise))
1346 ));
1347 __state_->__release_shared();
1348 }
1349}
1350
Howard Hinnantc834c512011-11-29 18:15:50 +00001351template <class _Rp>
1352future<_Rp>
1353promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001354{
1355 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001356 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001357 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001358}
1359
Howard Hinnantc834c512011-11-29 18:15:50 +00001360template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001361void
Howard Hinnantc834c512011-11-29 18:15:50 +00001362promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001363{
1364 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001365 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001366 __state_->set_value(__r);
1367}
1368
Howard Hinnantc834c512011-11-29 18:15:50 +00001369template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001370void
Howard Hinnantc834c512011-11-29 18:15:50 +00001371promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001372{
1373 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001374 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001375 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001376}
1377
Howard Hinnantc834c512011-11-29 18:15:50 +00001378template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001379void
Howard Hinnantc834c512011-11-29 18:15:50 +00001380promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001381{
Marshall Clow2b36f572016-05-16 16:55:32 +00001382 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001383 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001384 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001385 __state_->set_exception(__p);
1386}
1387
Howard Hinnantc834c512011-11-29 18:15:50 +00001388template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001389void
Howard Hinnantc834c512011-11-29 18:15:50 +00001390promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001391{
1392 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001393 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001394 __state_->set_value_at_thread_exit(__r);
1395}
1396
Howard Hinnantc834c512011-11-29 18:15:50 +00001397template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001398void
Howard Hinnantc834c512011-11-29 18:15:50 +00001399promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001400{
1401 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001402 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001403 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001404}
1405
Howard Hinnantc834c512011-11-29 18:15:50 +00001406template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001407void
Howard Hinnantc834c512011-11-29 18:15:50 +00001408promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001409{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001410 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001411 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001412 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001413 __state_->set_exception_at_thread_exit(__p);
1414}
1415
1416// promise<R&>
1417
Howard Hinnantc834c512011-11-29 18:15:50 +00001418template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001419class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001420{
Howard Hinnantc834c512011-11-29 18:15:50 +00001421 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001422
Howard Hinnant684902d2010-09-22 14:16:26 +00001423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001424 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001425
1426 template <class> friend class packaged_task;
1427
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001428public:
1429 promise();
1430 template <class _Allocator>
1431 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001432 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001433 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001434 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1435 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001436 ~promise();
1437
1438 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001440 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001441 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001442 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001443 return *this;
1444 }
1445 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001446
Howard Hinnant684902d2010-09-22 14:16:26 +00001447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001448 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001449
1450 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001451 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001452
1453 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001454 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001455 void set_exception(exception_ptr __p);
1456
1457 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001458 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001459 void set_exception_at_thread_exit(exception_ptr __p);
1460};
1461
Howard Hinnantc834c512011-11-29 18:15:50 +00001462template <class _Rp>
1463promise<_Rp&>::promise()
1464 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001465{
1466}
1467
Howard Hinnantc834c512011-11-29 18:15:50 +00001468template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001469template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001470promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001471{
Eric Fiselier0d109272014-10-23 06:24:45 +00001472 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1473 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001474 typedef __allocator_destructor<_A2> _D2;
1475 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001476 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001477 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001478 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001479}
1480
Howard Hinnantc834c512011-11-29 18:15:50 +00001481template <class _Rp>
1482promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001483{
1484 if (__state_)
1485 {
1486 if (!__state_->__has_value() && __state_->use_count() > 1)
1487 __state_->set_exception(make_exception_ptr(
1488 future_error(make_error_code(future_errc::broken_promise))
1489 ));
1490 __state_->__release_shared();
1491 }
1492}
1493
Howard Hinnantc834c512011-11-29 18:15:50 +00001494template <class _Rp>
1495future<_Rp&>
1496promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001497{
1498 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001499 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001500 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001501}
1502
Howard Hinnantc834c512011-11-29 18:15:50 +00001503template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504void
Howard Hinnantc834c512011-11-29 18:15:50 +00001505promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001506{
1507 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001508 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001509 __state_->set_value(__r);
1510}
1511
Howard Hinnantc834c512011-11-29 18:15:50 +00001512template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001513void
Howard Hinnantc834c512011-11-29 18:15:50 +00001514promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001515{
Marshall Clow2b36f572016-05-16 16:55:32 +00001516 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001517 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001518 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001519 __state_->set_exception(__p);
1520}
1521
Howard Hinnantc834c512011-11-29 18:15:50 +00001522template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001523void
Howard Hinnantc834c512011-11-29 18:15:50 +00001524promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001525{
1526 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001527 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001528 __state_->set_value_at_thread_exit(__r);
1529}
1530
Howard Hinnantc834c512011-11-29 18:15:50 +00001531template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001532void
Howard Hinnantc834c512011-11-29 18:15:50 +00001533promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001534{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001535 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001536 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001537 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001538 __state_->set_exception_at_thread_exit(__p);
1539}
1540
1541// promise<void>
1542
1543template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001544class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001545{
1546 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001547
Howard Hinnant684902d2010-09-22 14:16:26 +00001548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001549 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001550
1551 template <class> friend class packaged_task;
1552
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001553public:
1554 promise();
1555 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001556 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001557 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001559 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001560 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1561 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001562 ~promise();
1563
1564 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001566 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001567 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001568 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001569 return *this;
1570 }
1571 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001572
Howard Hinnant684902d2010-09-22 14:16:26 +00001573 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001574 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001575
1576 // retrieving the result
1577 future<void> get_future();
1578
1579 // setting the result
1580 void set_value();
1581 void set_exception(exception_ptr __p);
1582
1583 // setting the result with deferred notification
1584 void set_value_at_thread_exit();
1585 void set_exception_at_thread_exit(exception_ptr __p);
1586};
1587
1588template <class _Alloc>
1589promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1590{
Eric Fiselier0d109272014-10-23 06:24:45 +00001591 typedef __assoc_sub_state_alloc<_Alloc> _State;
1592 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001593 typedef __allocator_destructor<_A2> _D2;
1594 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001595 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001596 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001597 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001598}
1599
Howard Hinnantc834c512011-11-29 18:15:50 +00001600template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001601inline _LIBCPP_INLINE_VISIBILITY
1602void
Howard Hinnant22448042012-07-21 17:46:55 +00001603swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001604{
1605 __x.swap(__y);
1606}
1607
Howard Hinnantc834c512011-11-29 18:15:50 +00001608template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001609 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001610 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001611
Howard Hinnantccdd2032010-08-30 18:46:21 +00001612// packaged_task
1613
1614template<class _Fp> class __packaged_task_base;
1615
Howard Hinnantc834c512011-11-29 18:15:50 +00001616template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001617class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001618{
1619 __packaged_task_base(const __packaged_task_base&);
1620 __packaged_task_base& operator=(const __packaged_task_base&);
1621public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001623 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001624 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001625 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001626 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001627 virtual void destroy() = 0;
1628 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001629 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001630};
1631
1632template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1633
Howard Hinnantc834c512011-11-29 18:15:50 +00001634template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001635class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001636 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001637{
Howard Hinnantc834c512011-11-29 18:15:50 +00001638 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001639public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001640 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001641 explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001642 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001643 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001644 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001645 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001646 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001647 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001648 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001649 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001650 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001651 virtual void destroy();
1652 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001653 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001654};
1655
Howard Hinnantc834c512011-11-29 18:15:50 +00001656template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001657void
Howard Hinnantc834c512011-11-29 18:15:50 +00001658__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001659 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001660{
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001661 ::new ((void*)__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001662}
1663
Howard Hinnantc834c512011-11-29 18:15:50 +00001664template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001665void
Howard Hinnantc834c512011-11-29 18:15:50 +00001666__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001667{
Howard Hinnantc834c512011-11-29 18:15:50 +00001668 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001669}
1670
Howard Hinnantc834c512011-11-29 18:15:50 +00001671template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001672void
Howard Hinnantc834c512011-11-29 18:15:50 +00001673__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001674{
Eric Fiselier0d109272014-10-23 06:24:45 +00001675 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1676 typedef allocator_traits<_Ap> _ATraits;
1677 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001678 _Ap __a(__f_.second());
1679 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001680 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001681}
1682
Howard Hinnantc834c512011-11-29 18:15:50 +00001683template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1684_Rp
1685__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001686{
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05001687 return _VSTD::__invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001688}
1689
Howard Hinnant944510a2011-06-14 19:58:17 +00001690template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001691
Howard Hinnantc834c512011-11-29 18:15:50 +00001692template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001693class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001694{
Howard Hinnantc834c512011-11-29 18:15:50 +00001695 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001696
1697 _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
1698 __base* __get_buf() { return (__base*)&__buf_; }
1699
Howard Hinnant022c7482013-01-21 17:26:55 +00001700 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001701 __base* __f_;
1702
1703public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001704 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001705
1706 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001707 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001708 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001709 template<class _Fp>
1710 __packaged_task_function(_Fp&& __f);
1711 template<class _Fp, class _Alloc>
1712 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001713
Howard Hinnant22448042012-07-21 17:46:55 +00001714 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1715 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001716
1717 __packaged_task_function(const __packaged_task_function&) = delete;
1718 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1719
1720 ~__packaged_task_function();
1721
Howard Hinnant22448042012-07-21 17:46:55 +00001722 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001723
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001725 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001726};
1727
Howard Hinnantc834c512011-11-29 18:15:50 +00001728template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001729__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001730{
1731 if (__f.__f_ == nullptr)
1732 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001733 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001734 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001735 __f.__f_->__move_to(__get_buf());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001736 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001737 }
1738 else
1739 {
1740 __f_ = __f.__f_;
1741 __f.__f_ = nullptr;
1742 }
1743}
1744
Howard Hinnantc834c512011-11-29 18:15:50 +00001745template<class _Rp, class ..._ArgTypes>
1746template <class _Fp>
1747__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001748 : __f_(nullptr)
1749{
Marshall Clow733d60e2014-04-07 13:32:26 +00001750 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001751 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001752 if (sizeof(_FF) <= sizeof(__buf_))
1753 {
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001754 ::new ((void*)&__buf_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001755 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001756 }
1757 else
1758 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001759 typedef allocator<_FF> _Ap;
1760 _Ap __a;
1761 typedef __allocator_destructor<_Ap> _Dp;
1762 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001763 ::new ((void*)__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001764 __f_ = __hold.release();
1765 }
1766}
1767
Howard Hinnantc834c512011-11-29 18:15:50 +00001768template<class _Rp, class ..._ArgTypes>
1769template <class _Fp, class _Alloc>
1770__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1771 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001772 : __f_(nullptr)
1773{
Marshall Clow733d60e2014-04-07 13:32:26 +00001774 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001775 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001776 if (sizeof(_FF) <= sizeof(__buf_))
1777 {
1778 __f_ = (__base*)&__buf_;
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001779 ::new ((void*)__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001780 }
1781 else
1782 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001783 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001784 _Ap __a(__a0);
1785 typedef __allocator_destructor<_Ap> _Dp;
1786 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001787 ::new ((void*)_VSTD::addressof(*__hold.get()))
Eric Fiselier0d109272014-10-23 06:24:45 +00001788 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1789 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001790 }
1791}
1792
Howard Hinnantc834c512011-11-29 18:15:50 +00001793template<class _Rp, class ..._ArgTypes>
1794__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001795__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001796{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001797 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001798 __f_->destroy();
1799 else if (__f_)
1800 __f_->destroy_deallocate();
1801 __f_ = nullptr;
1802 if (__f.__f_ == nullptr)
1803 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001804 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001805 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001806 __f.__f_->__move_to(__get_buf());
1807 __f_ = __get_buf();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001808 }
1809 else
1810 {
1811 __f_ = __f.__f_;
1812 __f.__f_ = nullptr;
1813 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001814 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001815}
1816
Howard Hinnantc834c512011-11-29 18:15:50 +00001817template<class _Rp, class ..._ArgTypes>
1818__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001819{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001820 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001821 __f_->destroy();
1822 else if (__f_)
1823 __f_->destroy_deallocate();
1824}
1825
Howard Hinnantc834c512011-11-29 18:15:50 +00001826template<class _Rp, class ..._ArgTypes>
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001827_LIBCPP_NO_CFI
Howard Hinnantccdd2032010-08-30 18:46:21 +00001828void
Howard Hinnant22448042012-07-21 17:46:55 +00001829__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001830{
1831 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1832 {
1833 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1834 __base* __t = (__base*)&__tempbuf;
1835 __f_->__move_to(__t);
1836 __f_->destroy();
1837 __f_ = nullptr;
1838 __f.__f_->__move_to((__base*)&__buf_);
1839 __f.__f_->destroy();
1840 __f.__f_ = nullptr;
1841 __f_ = (__base*)&__buf_;
1842 __t->__move_to((__base*)&__f.__buf_);
1843 __t->destroy();
1844 __f.__f_ = (__base*)&__f.__buf_;
1845 }
1846 else if (__f_ == (__base*)&__buf_)
1847 {
1848 __f_->__move_to((__base*)&__f.__buf_);
1849 __f_->destroy();
1850 __f_ = __f.__f_;
1851 __f.__f_ = (__base*)&__f.__buf_;
1852 }
1853 else if (__f.__f_ == (__base*)&__f.__buf_)
1854 {
1855 __f.__f_->__move_to((__base*)&__buf_);
1856 __f.__f_->destroy();
1857 __f.__f_ = __f_;
1858 __f_ = (__base*)&__buf_;
1859 }
1860 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001861 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001862}
1863
Howard Hinnantc834c512011-11-29 18:15:50 +00001864template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001865inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001866_Rp
1867__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001868{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001869 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001870}
1871
Howard Hinnantc834c512011-11-29 18:15:50 +00001872template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001873class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001874{
1875public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00001876 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00001877
1878private:
1879 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1880 promise<result_type> __p_;
1881
1882public:
1883 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00001884 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001885 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00001886 template <class _Fp,
1887 class = typename enable_if
1888 <
1889 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001890 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00001891 packaged_task
1892 >::value
1893 >::type
1894 >
Howard Hinnant684902d2010-09-22 14:16:26 +00001895 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001896 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00001897 template <class _Fp, class _Allocator,
1898 class = typename enable_if
1899 <
1900 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001901 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00001902 packaged_task
1903 >::value
1904 >::type
1905 >
1906 _LIBCPP_INLINE_VISIBILITY
1907 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1908 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1909 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001910 // ~packaged_task() = default;
1911
1912 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00001913 packaged_task(const packaged_task&) = delete;
1914 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001915
1916 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00001917 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001918 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001919 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001920 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001921 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001922 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001923 __f_ = _VSTD::move(__other.__f_);
1924 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001925 return *this;
1926 }
Howard Hinnant684902d2010-09-22 14:16:26 +00001927 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001928 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001929 {
1930 __f_.swap(__other.__f_);
1931 __p_.swap(__other.__p_);
1932 }
1933
Howard Hinnant684902d2010-09-22 14:16:26 +00001934 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001935 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001936
1937 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00001938 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001939 future<result_type> get_future() {return __p_.get_future();}
1940
1941 // execution
1942 void operator()(_ArgTypes... __args);
1943 void make_ready_at_thread_exit(_ArgTypes... __args);
1944
1945 void reset();
1946};
1947
Howard Hinnantc834c512011-11-29 18:15:50 +00001948template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001949void
Howard Hinnantc834c512011-11-29 18:15:50 +00001950packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001951{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001952 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001953 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001954 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001955 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001956#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001957 try
1958 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001959#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001960 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001961#ifndef _LIBCPP_NO_EXCEPTIONS
1962 }
1963 catch (...)
1964 {
1965 __p_.set_exception(current_exception());
1966 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001967#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001968}
1969
Howard Hinnantc834c512011-11-29 18:15:50 +00001970template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001971void
Howard Hinnantc834c512011-11-29 18:15:50 +00001972packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001973{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001974 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001975 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001976 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001977 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001978#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001979 try
1980 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001981#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001982 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001983#ifndef _LIBCPP_NO_EXCEPTIONS
1984 }
1985 catch (...)
1986 {
1987 __p_.set_exception_at_thread_exit(current_exception());
1988 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001989#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001990}
1991
Howard Hinnantc834c512011-11-29 18:15:50 +00001992template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001993void
Howard Hinnantc834c512011-11-29 18:15:50 +00001994packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001995{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001996 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00001997 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001998 __p_ = promise<result_type>();
1999}
2000
2001template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002002class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002003{
2004public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002005 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002006
2007private:
2008 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2009 promise<result_type> __p_;
2010
2011public:
2012 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002013 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002014 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002015 template <class _Fp,
2016 class = typename enable_if
2017 <
2018 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002019 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002020 packaged_task
2021 >::value
2022 >::type
2023 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002024 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002025 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002026 template <class _Fp, class _Allocator,
2027 class = typename enable_if
2028 <
2029 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002030 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002031 packaged_task
2032 >::value
2033 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002034 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002035 _LIBCPP_INLINE_VISIBILITY
2036 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2037 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2038 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002039 // ~packaged_task() = default;
2040
2041 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002042 packaged_task(const packaged_task&) = delete;
2043 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002044
2045 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002046 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002047 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002048 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002049 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002050 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002051 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002052 __f_ = _VSTD::move(__other.__f_);
2053 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002054 return *this;
2055 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002057 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002058 {
2059 __f_.swap(__other.__f_);
2060 __p_.swap(__other.__p_);
2061 }
2062
Howard Hinnant684902d2010-09-22 14:16:26 +00002063 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002064 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002065
2066 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002067 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002068 future<result_type> get_future() {return __p_.get_future();}
2069
2070 // execution
2071 void operator()(_ArgTypes... __args);
2072 void make_ready_at_thread_exit(_ArgTypes... __args);
2073
2074 void reset();
2075};
2076
2077template<class ..._ArgTypes>
2078void
2079packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2080{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002082 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002083 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002084 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002085#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002086 try
2087 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002088#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002089 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002090 __p_.set_value();
2091#ifndef _LIBCPP_NO_EXCEPTIONS
2092 }
2093 catch (...)
2094 {
2095 __p_.set_exception(current_exception());
2096 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002097#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002098}
2099
2100template<class ..._ArgTypes>
2101void
2102packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2103{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002104 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002105 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002106 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002107 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002108#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002109 try
2110 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002111#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002112 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002113 __p_.set_value_at_thread_exit();
2114#ifndef _LIBCPP_NO_EXCEPTIONS
2115 }
2116 catch (...)
2117 {
2118 __p_.set_exception_at_thread_exit(current_exception());
2119 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002120#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002121}
2122
2123template<class ..._ArgTypes>
2124void
2125packaged_task<void(_ArgTypes...)>::reset()
2126{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002127 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002128 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002129 __p_ = promise<result_type>();
2130}
2131
jasonliubdad63b2021-03-24 22:31:58 +00002132template <class _Rp, class... _ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002133inline _LIBCPP_INLINE_VISIBILITY
2134void
jasonliubdad63b2021-03-24 22:31:58 +00002135swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002136{
2137 __x.swap(__y);
2138}
2139
Marshall Clowa0a057e2017-11-27 20:47:54 +00002140template <class _Callable, class _Alloc>
2141struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2142 : public true_type {};
2143
Howard Hinnantc834c512011-11-29 18:15:50 +00002144template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002145_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002146__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002147{
Howard Hinnantc834c512011-11-29 18:15:50 +00002148 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2149 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2150 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002151}
2152
Howard Hinnantc834c512011-11-29 18:15:50 +00002153template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002154_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002155__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002156{
Howard Hinnantc834c512011-11-29 18:15:50 +00002157 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2158 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2159 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2160 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002161}
2162
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002163#ifndef _LIBCPP_CXX03_LANG
2164
Howard Hinnantc834c512011-11-29 18:15:50 +00002165template <class _Fp, class... _Args>
Louis Dionne3b967d02019-12-10 18:00:42 -05002166class _LIBCPP_HIDDEN __async_func
Howard Hinnant95cfd872011-05-19 15:05:04 +00002167{
Howard Hinnantc834c512011-11-29 18:15:50 +00002168 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002169
2170public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002171 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002172
2173 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002174 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002175 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002176
2177 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002178 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002179
Howard Hinnantc834c512011-11-29 18:15:50 +00002180 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002181 {
2182 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2183 return __execute(_Index());
2184 }
2185private:
2186 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002187 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002188 __execute(__tuple_indices<_Indices...>)
2189 {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002190 return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002191 }
2192};
2193
Marshall Clowd56a5b62013-11-03 22:06:53 +00002194inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002195{ return (int(__policy) & int(__value)) != 0; }
2196
Howard Hinnantc834c512011-11-29 18:15:50 +00002197template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002198_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002199future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2200async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002201{
Howard Hinnantc834c512011-11-29 18:15:50 +00002202 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2203 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002204
2205#ifndef _LIBCPP_NO_EXCEPTIONS
2206 try
2207 {
2208#endif
2209 if (__does_policy_contain(__policy, launch::async))
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002210 return _VSTD::__make_async_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
2211 _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002212#ifndef _LIBCPP_NO_EXCEPTIONS
2213 }
2214 catch ( ... ) { if (__policy == launch::async) throw ; }
2215#endif
2216
2217 if (__does_policy_contain(__policy, launch::deferred))
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002218 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
2219 _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002220 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002221}
2222
Howard Hinnantc834c512011-11-29 18:15:50 +00002223template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002224_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002225future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2226async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002227{
Howard Hinnantc834c512011-11-29 18:15:50 +00002228 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002229 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002230}
2231
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002232#endif // C++03
Howard Hinnantccdd2032010-08-30 18:46:21 +00002233
Howard Hinnante6a10852010-09-03 21:46:37 +00002234// shared_future
2235
Howard Hinnantc834c512011-11-29 18:15:50 +00002236template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002237class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002238{
Howard Hinnantc834c512011-11-29 18:15:50 +00002239 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002240
2241public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002243 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002244 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002245 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002246 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002248 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002249 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002250 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002251 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002252 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002253 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002254 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant684902d2010-09-22 14:16:26 +00002255 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002256 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002257 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002258 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002259 return *this;
2260 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002261
2262 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002263 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002264 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002265
Howard Hinnant684902d2010-09-22 14:16:26 +00002266 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002267 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002268
2269 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002270 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002271 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002272
Howard Hinnant684902d2010-09-22 14:16:26 +00002273 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002274 void wait() const {__state_->wait();}
2275 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002276 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002277 future_status
2278 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2279 {return __state_->wait_for(__rel_time);}
2280 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002281 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002282 future_status
2283 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2284 {return __state_->wait_until(__abs_time);}
2285};
2286
Howard Hinnantc834c512011-11-29 18:15:50 +00002287template <class _Rp>
2288shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002289{
2290 if (__state_)
2291 __state_->__release_shared();
2292}
2293
Howard Hinnantc834c512011-11-29 18:15:50 +00002294template <class _Rp>
2295shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002296shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002297{
2298 if (__rhs.__state_)
2299 __rhs.__state_->__add_shared();
2300 if (__state_)
2301 __state_->__release_shared();
2302 __state_ = __rhs.__state_;
2303 return *this;
2304}
2305
Howard Hinnantc834c512011-11-29 18:15:50 +00002306template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002307class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002308{
Howard Hinnantc834c512011-11-29 18:15:50 +00002309 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002310
2311public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002312 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002313 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002315 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2316 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002318 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002319 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002320 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002321 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002322 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002323 ~shared_future();
2324 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002326 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002327 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002328 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002329 return *this;
2330 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002331
2332 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002334 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002335
Howard Hinnant684902d2010-09-22 14:16:26 +00002336 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002337 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002338
2339 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002340 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002341 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002342
Howard Hinnant684902d2010-09-22 14:16:26 +00002343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002344 void wait() const {__state_->wait();}
2345 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002346 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002347 future_status
2348 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2349 {return __state_->wait_for(__rel_time);}
2350 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002351 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002352 future_status
2353 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2354 {return __state_->wait_until(__abs_time);}
2355};
2356
Howard Hinnantc834c512011-11-29 18:15:50 +00002357template <class _Rp>
2358shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002359{
2360 if (__state_)
2361 __state_->__release_shared();
2362}
2363
Howard Hinnantc834c512011-11-29 18:15:50 +00002364template <class _Rp>
2365shared_future<_Rp&>&
2366shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002367{
2368 if (__rhs.__state_)
2369 __rhs.__state_->__add_shared();
2370 if (__state_)
2371 __state_->__release_shared();
2372 __state_ = __rhs.__state_;
2373 return *this;
2374}
2375
2376template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002377class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002378{
2379 __assoc_sub_state* __state_;
2380
2381public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002383 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002385 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2386 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002388 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002389 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002391 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002392 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002393 ~shared_future();
2394 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002396 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002397 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002398 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002399 return *this;
2400 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002401
2402 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002403 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002404 void get() const {__state_->copy();}
2405
Howard Hinnant684902d2010-09-22 14:16:26 +00002406 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002407 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002408
2409 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002411 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002412
Howard Hinnant684902d2010-09-22 14:16:26 +00002413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002414 void wait() const {__state_->wait();}
2415 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002417 future_status
2418 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2419 {return __state_->wait_for(__rel_time);}
2420 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002422 future_status
2423 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2424 {return __state_->wait_until(__abs_time);}
2425};
2426
Howard Hinnantc834c512011-11-29 18:15:50 +00002427template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002428inline _LIBCPP_INLINE_VISIBILITY
2429void
Howard Hinnant22448042012-07-21 17:46:55 +00002430swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002431{
2432 __x.swap(__y);
2433}
2434
Howard Hinnantc834c512011-11-29 18:15:50 +00002435template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002436inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002437shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002438future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002439{
Howard Hinnantc834c512011-11-29 18:15:50 +00002440 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002441}
2442
Howard Hinnantc834c512011-11-29 18:15:50 +00002443template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002444inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002445shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002446future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002447{
Howard Hinnantc834c512011-11-29 18:15:50 +00002448 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002449}
2450
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002451inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002452shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002453future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002454{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002455 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002456}
2457
Howard Hinnantc51e1022010-05-11 19:42:16 +00002458_LIBCPP_END_NAMESPACE_STD
2459
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002460#endif // !_LIBCPP_HAS_NO_THREADS
2461
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002462#endif // _LIBCPP_FUTURE