blob: d49bc809783bf5e721e2b3a9327c39d515faaf2c [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>
Arthur O'Dwyer423e14b2021-12-13 19:21:38 -0500369#include <__utility/auto_cast.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>
Mark de Weverce8f12c2021-12-22 18:14:14 +0100377#include <version>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000378
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000379#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Arthur O'Dwyer6eeaa002022-02-01 20:16:40 -0500380# pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000381#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000382
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000383#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000384#error <future> is not supported on this single threaded system
385#else // !_LIBCPP_HAS_NO_THREADS
386
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387_LIBCPP_BEGIN_NAMESPACE_STD
388
389//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000390_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000391{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000392 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000393 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000394 no_state,
395 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000396};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000397_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000398
Howard Hinnant684902d2010-09-22 14:16:26 +0000399template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000400struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000401
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000402#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
403template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000404struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000405#endif
406
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000409{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000410 async = 1,
411 deferred = 2,
412 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000413};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000414_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000415
Howard Hinnantda760a82013-06-29 18:38:17 +0000416#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
417
Howard Hinnantda760a82013-06-29 18:38:17 +0000418typedef underlying_type<launch>::type __launch_underlying_type;
Howard Hinnantda760a82013-06-29 18:38:17 +0000419
420inline _LIBCPP_INLINE_VISIBILITY
421_LIBCPP_CONSTEXPR
422launch
423operator&(launch __x, launch __y)
424{
425 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
426 static_cast<__launch_underlying_type>(__y));
427}
428
429inline _LIBCPP_INLINE_VISIBILITY
430_LIBCPP_CONSTEXPR
431launch
432operator|(launch __x, launch __y)
433{
434 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
435 static_cast<__launch_underlying_type>(__y));
436}
437
438inline _LIBCPP_INLINE_VISIBILITY
439_LIBCPP_CONSTEXPR
440launch
441operator^(launch __x, launch __y)
442{
443 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
444 static_cast<__launch_underlying_type>(__y));
445}
446
447inline _LIBCPP_INLINE_VISIBILITY
448_LIBCPP_CONSTEXPR
449launch
450operator~(launch __x)
451{
Howard Hinnant373d7602013-07-02 18:01:41 +0000452 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000453}
454
455inline _LIBCPP_INLINE_VISIBILITY
456launch&
457operator&=(launch& __x, launch __y)
458{
459 __x = __x & __y; return __x;
460}
461
462inline _LIBCPP_INLINE_VISIBILITY
463launch&
464operator|=(launch& __x, launch __y)
465{
466 __x = __x | __y; return __x;
467}
468
469inline _LIBCPP_INLINE_VISIBILITY
470launch&
471operator^=(launch& __x, launch __y)
472{
473 __x = __x ^ __y; return __x;
474}
475
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400476#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
Howard Hinnantda760a82013-06-29 18:38:17 +0000477
Howard Hinnantc51e1022010-05-11 19:42:16 +0000478//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000479_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000480{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000481 ready,
482 timeout,
483 deferred
484};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000485_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000486
Howard Hinnant8331b762013-03-06 23:30:19 +0000487_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000488const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000489
490inline _LIBCPP_INLINE_VISIBILITY
491error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000492make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000493{
494 return error_code(static_cast<int>(__e), future_category());
495}
496
497inline _LIBCPP_INLINE_VISIBILITY
498error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000499make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000500{
501 return error_condition(static_cast<int>(__e), future_category());
502}
503
Mehdi Amini228053d2017-05-04 17:08:54 +0000504class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000505 : public logic_error
506{
507 error_code __ec_;
508public:
509 future_error(error_code __ec);
Marek Kurdejf3197922021-04-01 08:29:55 +0200510
Howard Hinnant684902d2010-09-22 14:16:26 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000512 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000513
Dimitry Andric47269ce2020-03-13 19:36:26 +0100514 future_error(const future_error&) _NOEXCEPT = default;
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000515 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000516};
517
Louis Dionne16fe2952018-07-11 23:14:33 +0000518_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000519#ifndef _LIBCPP_NO_EXCEPTIONS
520_LIBCPP_AVAILABILITY_FUTURE_ERROR
521#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000522void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000523{
524#ifndef _LIBCPP_NO_EXCEPTIONS
525 throw future_error(make_error_code(_Ev));
526#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000527 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000528 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000529#endif
530}
531
Mehdi Amini228053d2017-05-04 17:08:54 +0000532class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000533 : public __shared_count
534{
535protected:
536 exception_ptr __exception_;
537 mutable mutex __mut_;
538 mutable condition_variable __cv_;
539 unsigned __state_;
540
Howard Hinnant719bda32011-05-28 14:41:13 +0000541 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000542 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000543public:
544 enum
545 {
546 __constructed = 1,
547 __future_attached = 2,
548 ready = 4,
549 deferred = 8
550 };
551
Howard Hinnant684902d2010-09-22 14:16:26 +0000552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000553 __assoc_sub_state() : __state_(0) {}
554
Howard Hinnant684902d2010-09-22 14:16:26 +0000555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000556 bool __has_value() const
557 {return (__state_ & __constructed) || (__exception_ != nullptr);}
558
Howard Hinnant684902d2010-09-22 14:16:26 +0000559 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000560 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000561 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000562 bool __has_future_attached = (__state_ & __future_attached) != 0;
563 if (__has_future_attached)
564 __throw_future_error(future_errc::future_already_retrieved);
565 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000566 __state_ |= __future_attached;
567 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000568
Howard Hinnant684902d2010-09-22 14:16:26 +0000569 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000570 void __set_deferred() {__state_ |= deferred;}
571
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000572 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000573 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000574 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000575
576 void set_value();
577 void set_value_at_thread_exit();
578
579 void set_exception(exception_ptr __p);
580 void set_exception_at_thread_exit(exception_ptr __p);
581
582 void copy();
583
Howard Hinnantccdd2032010-08-30 18:46:21 +0000584 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000585 template <class _Rep, class _Period>
586 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000587 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000588 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
589 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000590 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000591 future_status
592 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000593
594 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000595};
596
Howard Hinnantf4712b92010-08-28 21:01:06 +0000597template <class _Clock, class _Duration>
598future_status
599__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
600{
601 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000602 if (__state_ & deferred)
603 return future_status::deferred;
604 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000605 __cv_.wait_until(__lk, __abs_time);
606 if (__state_ & ready)
607 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000608 return future_status::timeout;
609}
610
611template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000612inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000613future_status
614__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
615{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000616 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000617}
618
Howard Hinnantc834c512011-11-29 18:15:50 +0000619template <class _Rp>
Louis Dionne3b967d02019-12-10 18:00:42 -0500620class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000621 : public __assoc_sub_state
622{
623 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000624 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000625protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000626 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000627
Howard Hinnant719bda32011-05-28 14:41:13 +0000628 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000629public:
630
631 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400632 void set_value(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000633
634 template <class _Arg>
Louis Dionne7b844362020-07-30 09:42:23 -0400635 void set_value_at_thread_exit(_Arg&& __arg);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000636
Howard Hinnantc834c512011-11-29 18:15:50 +0000637 _Rp move();
638 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000639};
640
Howard Hinnantc834c512011-11-29 18:15:50 +0000641template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000642void
Howard Hinnantc834c512011-11-29 18:15:50 +0000643__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000644{
645 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000646 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000647 delete this;
648}
649
Howard Hinnantc834c512011-11-29 18:15:50 +0000650template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000651template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000652_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000653void
Howard Hinnantc834c512011-11-29 18:15:50 +0000654__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000655{
656 unique_lock<mutex> __lk(this->__mut_);
657 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000658 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500659 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000660 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000661 __cv_.notify_all();
662}
663
Howard Hinnantc834c512011-11-29 18:15:50 +0000664template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000665template <class _Arg>
666void
Howard Hinnantc834c512011-11-29 18:15:50 +0000667__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000668{
669 unique_lock<mutex> __lk(this->__mut_);
670 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000671 __throw_future_error(future_errc::promise_already_satisfied);
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500672 ::new ((void*)&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000673 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000674 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675}
676
Howard Hinnantc834c512011-11-29 18:15:50 +0000677template <class _Rp>
678_Rp
679__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000680{
681 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000682 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000683 if (this->__exception_ != nullptr)
684 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000685 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000686}
687
Howard Hinnantc834c512011-11-29 18:15:50 +0000688template <class _Rp>
689typename add_lvalue_reference<_Rp>::type
690__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000691{
692 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000693 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000694 if (this->__exception_ != nullptr)
695 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000696 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000697}
698
Howard Hinnantc834c512011-11-29 18:15:50 +0000699template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000700class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000701 : public __assoc_sub_state
702{
703 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000704 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000705protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000706 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000707
Howard Hinnant719bda32011-05-28 14:41:13 +0000708 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000709public:
710
Howard Hinnantc834c512011-11-29 18:15:50 +0000711 void set_value(_Rp& __arg);
712 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000713
Howard Hinnantc834c512011-11-29 18:15:50 +0000714 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715};
716
Howard Hinnantc834c512011-11-29 18:15:50 +0000717template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000718void
Howard Hinnantc834c512011-11-29 18:15:50 +0000719__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000720{
721 delete this;
722}
723
Howard Hinnantc834c512011-11-29 18:15:50 +0000724template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000725void
Howard Hinnantc834c512011-11-29 18:15:50 +0000726__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000727{
728 unique_lock<mutex> __lk(this->__mut_);
729 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000730 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000731 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000732 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000733 __cv_.notify_all();
734}
735
Howard Hinnantc834c512011-11-29 18:15:50 +0000736template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000737void
Howard Hinnantc834c512011-11-29 18:15:50 +0000738__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000739{
740 unique_lock<mutex> __lk(this->__mut_);
741 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000742 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000743 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000744 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000745 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000746}
747
Howard Hinnantc834c512011-11-29 18:15:50 +0000748template <class _Rp>
749_Rp&
750__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000751{
752 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000753 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000754 if (this->__exception_ != nullptr)
755 rethrow_exception(this->__exception_);
756 return *__value_;
757}
758
Howard Hinnantc834c512011-11-29 18:15:50 +0000759template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000760class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000761 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000762{
Howard Hinnantc834c512011-11-29 18:15:50 +0000763 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000764 _Alloc __alloc_;
765
Howard Hinnant719bda32011-05-28 14:41:13 +0000766 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000767public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000768 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000769 explicit __assoc_state_alloc(const _Alloc& __a)
770 : __alloc_(__a) {}
771};
772
Howard Hinnantc834c512011-11-29 18:15:50 +0000773template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000774void
Howard Hinnantc834c512011-11-29 18:15:50 +0000775__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000776{
777 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000778 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000779 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
780 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000781 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000782 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000783 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000784 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000785}
786
Howard Hinnantc834c512011-11-29 18:15:50 +0000787template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000788class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000789 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000790{
Howard Hinnantc834c512011-11-29 18:15:50 +0000791 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000792 _Alloc __alloc_;
793
Howard Hinnant719bda32011-05-28 14:41:13 +0000794 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000795public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000796 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000797 explicit __assoc_state_alloc(const _Alloc& __a)
798 : __alloc_(__a) {}
799};
800
Howard Hinnantc834c512011-11-29 18:15:50 +0000801template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000802void
Howard Hinnantc834c512011-11-29 18:15:50 +0000803__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000804{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000805 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
806 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000807 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000808 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000809 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000810 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000811}
812
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000813template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000814class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000815 : public __assoc_sub_state
816{
817 typedef __assoc_sub_state base;
818 _Alloc __alloc_;
819
Howard Hinnant719bda32011-05-28 14:41:13 +0000820 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000821public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000822 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000823 explicit __assoc_sub_state_alloc(const _Alloc& __a)
824 : __alloc_(__a) {}
825};
826
827template <class _Alloc>
828void
Howard Hinnant719bda32011-05-28 14:41:13 +0000829__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000830{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000831 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
832 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000833 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000834 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000835 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000836 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000837}
838
Howard Hinnantc834c512011-11-29 18:15:50 +0000839template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000840class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000841 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000842{
Howard Hinnantc834c512011-11-29 18:15:50 +0000843 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000844
Howard Hinnantc834c512011-11-29 18:15:50 +0000845 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000846
847public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000848 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000849 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000850
851 virtual void __execute();
852};
853
Howard Hinnantc834c512011-11-29 18:15:50 +0000854template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000855inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000856__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
857 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000858{
859 this->__set_deferred();
860}
861
Howard Hinnantc834c512011-11-29 18:15:50 +0000862template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000863void
Howard Hinnantc834c512011-11-29 18:15:50 +0000864__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000865{
866#ifndef _LIBCPP_NO_EXCEPTIONS
867 try
868 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400869#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000870 this->set_value(__func_());
871#ifndef _LIBCPP_NO_EXCEPTIONS
872 }
873 catch (...)
874 {
875 this->set_exception(current_exception());
876 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400877#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000878}
879
Howard Hinnantc834c512011-11-29 18:15:50 +0000880template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000881class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000882 : public __assoc_sub_state
883{
884 typedef __assoc_sub_state base;
885
Howard Hinnantc834c512011-11-29 18:15:50 +0000886 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000887
888public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000889 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000890 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000891
892 virtual void __execute();
893};
894
Howard Hinnantc834c512011-11-29 18:15:50 +0000895template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000896inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000897__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
898 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000899{
900 this->__set_deferred();
901}
902
Howard Hinnantc834c512011-11-29 18:15:50 +0000903template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000904void
Howard Hinnantc834c512011-11-29 18:15:50 +0000905__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000906{
907#ifndef _LIBCPP_NO_EXCEPTIONS
908 try
909 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400910#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000911 __func_();
912 this->set_value();
913#ifndef _LIBCPP_NO_EXCEPTIONS
914 }
915 catch (...)
916 {
917 this->set_exception(current_exception());
918 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400919#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +0000920}
921
Howard Hinnantc834c512011-11-29 18:15:50 +0000922template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000923class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000924 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000925{
Howard Hinnantc834c512011-11-29 18:15:50 +0000926 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000927
Howard Hinnantc834c512011-11-29 18:15:50 +0000928 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000929
Howard Hinnant719bda32011-05-28 14:41:13 +0000930 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000931public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000932 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000933 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000934
935 virtual void __execute();
936};
937
Howard Hinnantc834c512011-11-29 18:15:50 +0000938template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000939inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000940__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
941 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000942{
943}
944
Howard Hinnantc834c512011-11-29 18:15:50 +0000945template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000946void
Howard Hinnantc834c512011-11-29 18:15:50 +0000947__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000948{
949#ifndef _LIBCPP_NO_EXCEPTIONS
950 try
951 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400952#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +0000953 this->set_value(__func_());
954#ifndef _LIBCPP_NO_EXCEPTIONS
955 }
956 catch (...)
957 {
958 this->set_exception(current_exception());
959 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -0400960#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +0000961}
962
Howard Hinnantc834c512011-11-29 18:15:50 +0000963template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000964void
Howard Hinnantc834c512011-11-29 18:15:50 +0000965__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000966{
967 this->wait();
968 base::__on_zero_shared();
969}
970
Howard Hinnantc834c512011-11-29 18:15:50 +0000971template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000972class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000973 : public __assoc_sub_state
974{
975 typedef __assoc_sub_state base;
976
Howard Hinnantc834c512011-11-29 18:15:50 +0000977 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000978
Howard Hinnant719bda32011-05-28 14:41:13 +0000979 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000980public:
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000981 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000982 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000983
984 virtual void __execute();
985};
986
Howard Hinnantc834c512011-11-29 18:15:50 +0000987template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000988inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000989__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
990 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000991{
992}
993
Howard Hinnantc834c512011-11-29 18:15:50 +0000994template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000995void
Howard Hinnantc834c512011-11-29 18:15:50 +0000996__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000997{
998#ifndef _LIBCPP_NO_EXCEPTIONS
999 try
1000 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001001#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +00001002 __func_();
1003 this->set_value();
1004#ifndef _LIBCPP_NO_EXCEPTIONS
1005 }
1006 catch (...)
1007 {
1008 this->set_exception(current_exception());
1009 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001010#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant95cfd872011-05-19 15:05:04 +00001011}
1012
Howard Hinnantc834c512011-11-29 18:15:50 +00001013template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001014void
Howard Hinnantc834c512011-11-29 18:15:50 +00001015__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001016{
1017 this->wait();
1018 base::__on_zero_shared();
1019}
1020
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001021template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1022template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001023
1024// future
1025
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001026template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001027
Howard Hinnantc834c512011-11-29 18:15:50 +00001028template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001029_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001030__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001031
Howard Hinnantc834c512011-11-29 18:15:50 +00001032template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001033_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00001034__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001035
Howard Hinnantc834c512011-11-29 18:15:50 +00001036template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001037class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001038{
Howard Hinnantc834c512011-11-29 18:15:50 +00001039 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001040
Howard Hinnantc834c512011-11-29 18:15:50 +00001041 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001042
1043 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001044 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001045
Howard Hinnantc834c512011-11-29 18:15:50 +00001046 template <class _R1, class _Fp>
1047 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1048 template <class _R1, class _Fp>
1049 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001050
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001051public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001052 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001053 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001055 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001056 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1057 future(const future&) = delete;
1058 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001060 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001061 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001062 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001063 return *this;
1064 }
Louis Dionne7b844362020-07-30 09:42:23 -04001065
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001066 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001067 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001068 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001069
1070 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001071 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001072
Howard Hinnant684902d2010-09-22 14:16:26 +00001073 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001074 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001075
1076 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001077 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001078 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001079
Howard Hinnant684902d2010-09-22 14:16:26 +00001080 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001081 void wait() const {__state_->wait();}
1082 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001083 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001084 future_status
1085 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1086 {return __state_->wait_for(__rel_time);}
1087 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001088 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001089 future_status
1090 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1091 {return __state_->wait_until(__abs_time);}
1092};
1093
Howard Hinnantc834c512011-11-29 18:15:50 +00001094template <class _Rp>
1095future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001096 : __state_(__state)
1097{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001098 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001099}
1100
Howard Hinnantccdd2032010-08-30 18:46:21 +00001101struct __release_shared_count
1102{
1103 void operator()(__shared_count* p) {p->__release_shared();}
1104};
1105
Howard Hinnantc834c512011-11-29 18:15:50 +00001106template <class _Rp>
1107future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001108{
1109 if (__state_)
1110 __state_->__release_shared();
1111}
1112
Howard Hinnantc834c512011-11-29 18:15:50 +00001113template <class _Rp>
1114_Rp
1115future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001116{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001117 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001118 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001119 __state_ = nullptr;
1120 return __s->move();
1121}
1122
Howard Hinnantc834c512011-11-29 18:15:50 +00001123template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001124class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001125{
Howard Hinnantc834c512011-11-29 18:15:50 +00001126 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001127
Howard Hinnantc834c512011-11-29 18:15:50 +00001128 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001129
1130 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001131 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001132
Howard Hinnantc834c512011-11-29 18:15:50 +00001133 template <class _R1, class _Fp>
1134 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1135 template <class _R1, class _Fp>
1136 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001137
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001138public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001139 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001140 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001142 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001143 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1144 future(const future&) = delete;
1145 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001146 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001147 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001148 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001149 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001150 return *this;
1151 }
Louis Dionne7b844362020-07-30 09:42:23 -04001152
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001153 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001154 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001155 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001156
1157 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001158 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001159
Howard Hinnant684902d2010-09-22 14:16:26 +00001160 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001161 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001162
1163 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001164 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001165 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001166
Howard Hinnant684902d2010-09-22 14:16:26 +00001167 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001168 void wait() const {__state_->wait();}
1169 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001170 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001171 future_status
1172 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1173 {return __state_->wait_for(__rel_time);}
1174 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001176 future_status
1177 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1178 {return __state_->wait_until(__abs_time);}
1179};
1180
Howard Hinnantc834c512011-11-29 18:15:50 +00001181template <class _Rp>
1182future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001183 : __state_(__state)
1184{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001185 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001186}
1187
Howard Hinnantc834c512011-11-29 18:15:50 +00001188template <class _Rp>
1189future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001190{
1191 if (__state_)
1192 __state_->__release_shared();
1193}
1194
Howard Hinnantc834c512011-11-29 18:15:50 +00001195template <class _Rp>
1196_Rp&
1197future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001198{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001199 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001200 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001201 __state_ = nullptr;
1202 return __s->copy();
1203}
1204
1205template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001206class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001207{
1208 __assoc_sub_state* __state_;
1209
1210 explicit future(__assoc_sub_state* __state);
1211
1212 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001213 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001214
Howard Hinnantc834c512011-11-29 18:15:50 +00001215 template <class _R1, class _Fp>
1216 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1217 template <class _R1, class _Fp>
1218 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001219
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001220public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001222 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001223 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001224 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001225 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1226 future(const future&) = delete;
1227 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001228 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001229 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001230 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001231 future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001232 return *this;
1233 }
Louis Dionne7b844362020-07-30 09:42:23 -04001234
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001235 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001236 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001237 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001238
1239 // retrieving the value
1240 void get();
1241
Howard Hinnant684902d2010-09-22 14:16:26 +00001242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001243 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001244
1245 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001246 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001247 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001248
Howard Hinnant684902d2010-09-22 14:16:26 +00001249 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001250 void wait() const {__state_->wait();}
1251 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001252 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001253 future_status
1254 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1255 {return __state_->wait_for(__rel_time);}
1256 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001257 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001258 future_status
1259 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1260 {return __state_->wait_until(__abs_time);}
1261};
1262
Howard Hinnantc834c512011-11-29 18:15:50 +00001263template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001264inline _LIBCPP_INLINE_VISIBILITY
1265void
Howard Hinnant22448042012-07-21 17:46:55 +00001266swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001267{
1268 __x.swap(__y);
1269}
1270
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001271// promise<R>
1272
Howard Hinnant944510a2011-06-14 19:58:17 +00001273template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001274
Howard Hinnantc834c512011-11-29 18:15:50 +00001275template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001276class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001277{
Howard Hinnantc834c512011-11-29 18:15:50 +00001278 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001279
Howard Hinnant684902d2010-09-22 14:16:26 +00001280 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001281 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001282
1283 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001284public:
1285 promise();
1286 template <class _Alloc>
1287 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001288 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001289 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001290 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1291 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001292 ~promise();
1293
1294 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001296 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001297 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001298 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001299 return *this;
1300 }
1301 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001302
Howard Hinnant684902d2010-09-22 14:16:26 +00001303 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001304 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001305
1306 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001307 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001308
1309 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001310 void set_value(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001311 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001312 void set_exception(exception_ptr __p);
1313
1314 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001315 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnantc834c512011-11-29 18:15:50 +00001316 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001317 void set_exception_at_thread_exit(exception_ptr __p);
1318};
1319
Howard Hinnantc834c512011-11-29 18:15:50 +00001320template <class _Rp>
1321promise<_Rp>::promise()
1322 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001323{
1324}
1325
Howard Hinnantc834c512011-11-29 18:15:50 +00001326template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001327template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001328promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001329{
Eric Fiselier0d109272014-10-23 06:24:45 +00001330 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1331 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001332 typedef __allocator_destructor<_A2> _D2;
1333 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001334 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001335 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001336 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001337}
1338
Howard Hinnantc834c512011-11-29 18:15:50 +00001339template <class _Rp>
1340promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001341{
1342 if (__state_)
1343 {
1344 if (!__state_->__has_value() && __state_->use_count() > 1)
1345 __state_->set_exception(make_exception_ptr(
1346 future_error(make_error_code(future_errc::broken_promise))
1347 ));
1348 __state_->__release_shared();
1349 }
1350}
1351
Howard Hinnantc834c512011-11-29 18:15:50 +00001352template <class _Rp>
1353future<_Rp>
1354promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001355{
1356 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001357 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001358 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001359}
1360
Howard Hinnantc834c512011-11-29 18:15:50 +00001361template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001362void
Howard Hinnantc834c512011-11-29 18:15:50 +00001363promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001364{
1365 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001366 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001367 __state_->set_value(__r);
1368}
1369
Howard Hinnantc834c512011-11-29 18:15:50 +00001370template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001371void
Howard Hinnantc834c512011-11-29 18:15:50 +00001372promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001373{
1374 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001375 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001376 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001377}
1378
Howard Hinnantc834c512011-11-29 18:15:50 +00001379template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001380void
Howard Hinnantc834c512011-11-29 18:15:50 +00001381promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001382{
Marshall Clow2b36f572016-05-16 16:55:32 +00001383 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001384 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001385 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001386 __state_->set_exception(__p);
1387}
1388
Howard Hinnantc834c512011-11-29 18:15:50 +00001389template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001390void
Howard Hinnantc834c512011-11-29 18:15:50 +00001391promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001392{
1393 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001394 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001395 __state_->set_value_at_thread_exit(__r);
1396}
1397
Howard Hinnantc834c512011-11-29 18:15:50 +00001398template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001399void
Howard Hinnantc834c512011-11-29 18:15:50 +00001400promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001401{
1402 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001403 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001404 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001405}
1406
Howard Hinnantc834c512011-11-29 18:15:50 +00001407template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001408void
Howard Hinnantc834c512011-11-29 18:15:50 +00001409promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001410{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001411 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001412 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001413 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001414 __state_->set_exception_at_thread_exit(__p);
1415}
1416
1417// promise<R&>
1418
Howard Hinnantc834c512011-11-29 18:15:50 +00001419template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001420class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001421{
Howard Hinnantc834c512011-11-29 18:15:50 +00001422 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001423
Howard Hinnant684902d2010-09-22 14:16:26 +00001424 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001425 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001426
1427 template <class> friend class packaged_task;
1428
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001429public:
1430 promise();
1431 template <class _Allocator>
1432 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001434 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001435 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1436 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001437 ~promise();
1438
1439 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001441 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001442 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001443 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001444 return *this;
1445 }
1446 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001447
Howard Hinnant684902d2010-09-22 14:16:26 +00001448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001449 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001450
1451 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001452 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001453
1454 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001455 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001456 void set_exception(exception_ptr __p);
1457
1458 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001459 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001460 void set_exception_at_thread_exit(exception_ptr __p);
1461};
1462
Howard Hinnantc834c512011-11-29 18:15:50 +00001463template <class _Rp>
1464promise<_Rp&>::promise()
1465 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001466{
1467}
1468
Howard Hinnantc834c512011-11-29 18:15:50 +00001469template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001470template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001471promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001472{
Eric Fiselier0d109272014-10-23 06:24:45 +00001473 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1474 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001475 typedef __allocator_destructor<_A2> _D2;
1476 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001477 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001478 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001479 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001480}
1481
Howard Hinnantc834c512011-11-29 18:15:50 +00001482template <class _Rp>
1483promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001484{
1485 if (__state_)
1486 {
1487 if (!__state_->__has_value() && __state_->use_count() > 1)
1488 __state_->set_exception(make_exception_ptr(
1489 future_error(make_error_code(future_errc::broken_promise))
1490 ));
1491 __state_->__release_shared();
1492 }
1493}
1494
Howard Hinnantc834c512011-11-29 18:15:50 +00001495template <class _Rp>
1496future<_Rp&>
1497promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001498{
1499 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001500 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001501 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001502}
1503
Howard Hinnantc834c512011-11-29 18:15:50 +00001504template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001505void
Howard Hinnantc834c512011-11-29 18:15:50 +00001506promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001507{
1508 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001509 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001510 __state_->set_value(__r);
1511}
1512
Howard Hinnantc834c512011-11-29 18:15:50 +00001513template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001514void
Howard Hinnantc834c512011-11-29 18:15:50 +00001515promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001516{
Marshall Clow2b36f572016-05-16 16:55:32 +00001517 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001518 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001519 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001520 __state_->set_exception(__p);
1521}
1522
Howard Hinnantc834c512011-11-29 18:15:50 +00001523template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001524void
Howard Hinnantc834c512011-11-29 18:15:50 +00001525promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001526{
1527 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001528 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001529 __state_->set_value_at_thread_exit(__r);
1530}
1531
Howard Hinnantc834c512011-11-29 18:15:50 +00001532template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001533void
Howard Hinnantc834c512011-11-29 18:15:50 +00001534promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001535{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001536 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001537 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001538 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001539 __state_->set_exception_at_thread_exit(__p);
1540}
1541
1542// promise<void>
1543
1544template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001545class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001546{
1547 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001548
Howard Hinnant684902d2010-09-22 14:16:26 +00001549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001550 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001551
1552 template <class> friend class packaged_task;
1553
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001554public:
1555 promise();
1556 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001557 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001558 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant684902d2010-09-22 14:16:26 +00001559 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001560 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001561 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1562 promise(const promise& __rhs) = delete;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001563 ~promise();
1564
1565 // assignment
Howard Hinnant684902d2010-09-22 14:16:26 +00001566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001567 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001568 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001569 promise(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001570 return *this;
1571 }
1572 promise& operator=(const promise& __rhs) = delete;
Louis Dionne7b844362020-07-30 09:42:23 -04001573
Howard Hinnant684902d2010-09-22 14:16:26 +00001574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001575 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001576
1577 // retrieving the result
1578 future<void> get_future();
1579
1580 // setting the result
1581 void set_value();
1582 void set_exception(exception_ptr __p);
1583
1584 // setting the result with deferred notification
1585 void set_value_at_thread_exit();
1586 void set_exception_at_thread_exit(exception_ptr __p);
1587};
1588
1589template <class _Alloc>
1590promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1591{
Eric Fiselier0d109272014-10-23 06:24:45 +00001592 typedef __assoc_sub_state_alloc<_Alloc> _State;
1593 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001594 typedef __allocator_destructor<_A2> _D2;
1595 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001596 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001597 ::new ((void*)_VSTD::addressof(*__hold.get())) _State(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001598 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001599}
1600
Howard Hinnantc834c512011-11-29 18:15:50 +00001601template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001602inline _LIBCPP_INLINE_VISIBILITY
1603void
Howard Hinnant22448042012-07-21 17:46:55 +00001604swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001605{
1606 __x.swap(__y);
1607}
1608
Howard Hinnantc834c512011-11-29 18:15:50 +00001609template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001610 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001611 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001612
Howard Hinnantccdd2032010-08-30 18:46:21 +00001613// packaged_task
1614
1615template<class _Fp> class __packaged_task_base;
1616
Howard Hinnantc834c512011-11-29 18:15:50 +00001617template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001618class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001619{
1620 __packaged_task_base(const __packaged_task_base&);
1621 __packaged_task_base& operator=(const __packaged_task_base&);
1622public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001623 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001624 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001625 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001626 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001627 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001628 virtual void destroy() = 0;
1629 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001630 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001631};
1632
1633template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1634
Howard Hinnantc834c512011-11-29 18:15:50 +00001635template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001636class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001637 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001638{
Howard Hinnantc834c512011-11-29 18:15:50 +00001639 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001640public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001641 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001642 explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001643 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001644 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001645 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001646 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001647 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001648 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001649 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001650 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001651 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001652 virtual void destroy();
1653 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001654 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001655};
1656
Howard Hinnantc834c512011-11-29 18:15:50 +00001657template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001658void
Howard Hinnantc834c512011-11-29 18:15:50 +00001659__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001660 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001661{
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001662 ::new ((void*)__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001663}
1664
Howard Hinnantc834c512011-11-29 18:15:50 +00001665template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001666void
Howard Hinnantc834c512011-11-29 18:15:50 +00001667__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001668{
Howard Hinnantc834c512011-11-29 18:15:50 +00001669 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001670}
1671
Howard Hinnantc834c512011-11-29 18:15:50 +00001672template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001673void
Howard Hinnantc834c512011-11-29 18:15:50 +00001674__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001675{
Eric Fiselier0d109272014-10-23 06:24:45 +00001676 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1677 typedef allocator_traits<_Ap> _ATraits;
1678 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001679 _Ap __a(__f_.second());
1680 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001681 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001682}
1683
Howard Hinnantc834c512011-11-29 18:15:50 +00001684template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1685_Rp
1686__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001687{
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05001688 return _VSTD::__invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001689}
1690
Howard Hinnant944510a2011-06-14 19:58:17 +00001691template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001692
Howard Hinnantc834c512011-11-29 18:15:50 +00001693template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001694class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001695{
Howard Hinnantc834c512011-11-29 18:15:50 +00001696 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001697
1698 _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
1699 __base* __get_buf() { return (__base*)&__buf_; }
1700
Howard Hinnant022c7482013-01-21 17:26:55 +00001701 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001702 __base* __f_;
1703
1704public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001705 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001706
1707 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001709 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001710 template<class _Fp>
1711 __packaged_task_function(_Fp&& __f);
1712 template<class _Fp, class _Alloc>
1713 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001714
Howard Hinnant22448042012-07-21 17:46:55 +00001715 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1716 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001717
1718 __packaged_task_function(const __packaged_task_function&) = delete;
1719 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1720
1721 ~__packaged_task_function();
1722
Howard Hinnant22448042012-07-21 17:46:55 +00001723 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001724
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001725 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001726 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001727};
1728
Howard Hinnantc834c512011-11-29 18:15:50 +00001729template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001730__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001731{
1732 if (__f.__f_ == nullptr)
1733 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001734 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001735 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001736 __f.__f_->__move_to(__get_buf());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001737 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001738 }
1739 else
1740 {
1741 __f_ = __f.__f_;
1742 __f.__f_ = nullptr;
1743 }
1744}
1745
Howard Hinnantc834c512011-11-29 18:15:50 +00001746template<class _Rp, class ..._ArgTypes>
1747template <class _Fp>
1748__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001749 : __f_(nullptr)
1750{
Marshall Clow733d60e2014-04-07 13:32:26 +00001751 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001752 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001753 if (sizeof(_FF) <= sizeof(__buf_))
1754 {
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001755 ::new ((void*)&__buf_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001756 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001757 }
1758 else
1759 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001760 typedef allocator<_FF> _Ap;
1761 _Ap __a;
1762 typedef __allocator_destructor<_Ap> _Dp;
1763 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001764 ::new ((void*)__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001765 __f_ = __hold.release();
1766 }
1767}
1768
Howard Hinnantc834c512011-11-29 18:15:50 +00001769template<class _Rp, class ..._ArgTypes>
1770template <class _Fp, class _Alloc>
1771__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1772 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001773 : __f_(nullptr)
1774{
Marshall Clow733d60e2014-04-07 13:32:26 +00001775 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001776 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001777 if (sizeof(_FF) <= sizeof(__buf_))
1778 {
1779 __f_ = (__base*)&__buf_;
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001780 ::new ((void*)__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001781 }
1782 else
1783 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001784 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001785 _Ap __a(__a0);
1786 typedef __allocator_destructor<_Ap> _Dp;
1787 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -05001788 ::new ((void*)_VSTD::addressof(*__hold.get()))
Eric Fiselier0d109272014-10-23 06:24:45 +00001789 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1790 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001791 }
1792}
1793
Howard Hinnantc834c512011-11-29 18:15:50 +00001794template<class _Rp, class ..._ArgTypes>
1795__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001796__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001797{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001798 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001799 __f_->destroy();
1800 else if (__f_)
1801 __f_->destroy_deallocate();
1802 __f_ = nullptr;
1803 if (__f.__f_ == nullptr)
1804 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001805 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001806 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001807 __f.__f_->__move_to(__get_buf());
1808 __f_ = __get_buf();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001809 }
1810 else
1811 {
1812 __f_ = __f.__f_;
1813 __f.__f_ = nullptr;
1814 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001815 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001816}
1817
Howard Hinnantc834c512011-11-29 18:15:50 +00001818template<class _Rp, class ..._ArgTypes>
1819__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001820{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001821 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001822 __f_->destroy();
1823 else if (__f_)
1824 __f_->destroy_deallocate();
1825}
1826
Howard Hinnantc834c512011-11-29 18:15:50 +00001827template<class _Rp, class ..._ArgTypes>
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001828_LIBCPP_NO_CFI
Howard Hinnantccdd2032010-08-30 18:46:21 +00001829void
Howard Hinnant22448042012-07-21 17:46:55 +00001830__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001831{
1832 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1833 {
1834 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1835 __base* __t = (__base*)&__tempbuf;
1836 __f_->__move_to(__t);
1837 __f_->destroy();
1838 __f_ = nullptr;
1839 __f.__f_->__move_to((__base*)&__buf_);
1840 __f.__f_->destroy();
1841 __f.__f_ = nullptr;
1842 __f_ = (__base*)&__buf_;
1843 __t->__move_to((__base*)&__f.__buf_);
1844 __t->destroy();
1845 __f.__f_ = (__base*)&__f.__buf_;
1846 }
1847 else if (__f_ == (__base*)&__buf_)
1848 {
1849 __f_->__move_to((__base*)&__f.__buf_);
1850 __f_->destroy();
1851 __f_ = __f.__f_;
1852 __f.__f_ = (__base*)&__f.__buf_;
1853 }
1854 else if (__f.__f_ == (__base*)&__f.__buf_)
1855 {
1856 __f.__f_->__move_to((__base*)&__buf_);
1857 __f.__f_->destroy();
1858 __f.__f_ = __f_;
1859 __f_ = (__base*)&__buf_;
1860 }
1861 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001862 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001863}
1864
Howard Hinnantc834c512011-11-29 18:15:50 +00001865template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001866inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001867_Rp
1868__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001869{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001870 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001871}
1872
Howard Hinnantc834c512011-11-29 18:15:50 +00001873template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001874class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001875{
1876public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00001877 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00001878
1879private:
1880 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1881 promise<result_type> __p_;
1882
1883public:
1884 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00001885 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001886 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00001887 template <class _Fp,
1888 class = typename enable_if
1889 <
1890 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001891 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00001892 packaged_task
1893 >::value
1894 >::type
1895 >
Howard Hinnant684902d2010-09-22 14:16:26 +00001896 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001897 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00001898 template <class _Fp, class _Allocator,
1899 class = typename enable_if
1900 <
1901 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00001902 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00001903 packaged_task
1904 >::value
1905 >::type
1906 >
1907 _LIBCPP_INLINE_VISIBILITY
1908 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1909 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
1910 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001911 // ~packaged_task() = default;
1912
1913 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00001914 packaged_task(const packaged_task&) = delete;
1915 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001916
1917 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00001918 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001919 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001920 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001921 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001922 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001923 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001924 __f_ = _VSTD::move(__other.__f_);
1925 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001926 return *this;
1927 }
Howard Hinnant684902d2010-09-22 14:16:26 +00001928 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001929 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001930 {
1931 __f_.swap(__other.__f_);
1932 __p_.swap(__other.__p_);
1933 }
1934
Howard Hinnant684902d2010-09-22 14:16:26 +00001935 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001936 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001937
1938 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00001939 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001940 future<result_type> get_future() {return __p_.get_future();}
1941
1942 // execution
1943 void operator()(_ArgTypes... __args);
1944 void make_ready_at_thread_exit(_ArgTypes... __args);
1945
1946 void reset();
1947};
1948
Howard Hinnantc834c512011-11-29 18:15:50 +00001949template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001950void
Howard Hinnantc834c512011-11-29 18:15:50 +00001951packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001952{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001953 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001954 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001955 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001956 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001957#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001958 try
1959 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001960#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001961 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001962#ifndef _LIBCPP_NO_EXCEPTIONS
1963 }
1964 catch (...)
1965 {
1966 __p_.set_exception(current_exception());
1967 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001968#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001969}
1970
Howard Hinnantc834c512011-11-29 18:15:50 +00001971template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001972void
Howard Hinnantc834c512011-11-29 18:15:50 +00001973packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001974{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001975 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001976 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001977 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00001978 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00001979#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001980 try
1981 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001982#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001983 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001984#ifndef _LIBCPP_NO_EXCEPTIONS
1985 }
1986 catch (...)
1987 {
1988 __p_.set_exception_at_thread_exit(current_exception());
1989 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001990#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00001991}
1992
Howard Hinnantc834c512011-11-29 18:15:50 +00001993template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001994void
Howard Hinnantc834c512011-11-29 18:15:50 +00001995packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001996{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001997 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00001998 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001999 __p_ = promise<result_type>();
2000}
2001
2002template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002003class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004{
2005public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002006 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002007
2008private:
2009 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2010 promise<result_type> __p_;
2011
2012public:
2013 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002015 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002016 template <class _Fp,
2017 class = typename enable_if
2018 <
2019 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002020 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002021 packaged_task
2022 >::value
2023 >::type
2024 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002025 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002026 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002027 template <class _Fp, class _Allocator,
2028 class = typename enable_if
2029 <
2030 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002031 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002032 packaged_task
2033 >::value
2034 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002035 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002036 _LIBCPP_INLINE_VISIBILITY
2037 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2038 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2039 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002040 // ~packaged_task() = default;
2041
2042 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002043 packaged_task(const packaged_task&) = delete;
2044 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002045
2046 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002048 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002049 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002050 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002051 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002052 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002053 __f_ = _VSTD::move(__other.__f_);
2054 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002055 return *this;
2056 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002057 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002058 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002059 {
2060 __f_.swap(__other.__f_);
2061 __p_.swap(__other.__p_);
2062 }
2063
Howard Hinnant684902d2010-09-22 14:16:26 +00002064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002065 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002066
2067 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002069 future<result_type> get_future() {return __p_.get_future();}
2070
2071 // execution
2072 void operator()(_ArgTypes... __args);
2073 void make_ready_at_thread_exit(_ArgTypes... __args);
2074
2075 void reset();
2076};
2077
2078template<class ..._ArgTypes>
2079void
2080packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2081{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002082 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002083 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002084 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002085 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002086#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002087 try
2088 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002089#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002090 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002091 __p_.set_value();
2092#ifndef _LIBCPP_NO_EXCEPTIONS
2093 }
2094 catch (...)
2095 {
2096 __p_.set_exception(current_exception());
2097 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002098#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002099}
2100
2101template<class ..._ArgTypes>
2102void
2103packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2104{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002105 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002106 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002107 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002108 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002109#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002110 try
2111 {
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002112#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002113 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002114 __p_.set_value_at_thread_exit();
2115#ifndef _LIBCPP_NO_EXCEPTIONS
2116 }
2117 catch (...)
2118 {
2119 __p_.set_exception_at_thread_exit(current_exception());
2120 }
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002121#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002122}
2123
2124template<class ..._ArgTypes>
2125void
2126packaged_task<void(_ArgTypes...)>::reset()
2127{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002128 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002129 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002130 __p_ = promise<result_type>();
2131}
2132
jasonliubdad63b2021-03-24 22:31:58 +00002133template <class _Rp, class... _ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002134inline _LIBCPP_INLINE_VISIBILITY
2135void
jasonliubdad63b2021-03-24 22:31:58 +00002136swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002137{
2138 __x.swap(__y);
2139}
2140
Marshall Clowa0a057e2017-11-27 20:47:54 +00002141template <class _Callable, class _Alloc>
2142struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2143 : public true_type {};
2144
Howard Hinnantc834c512011-11-29 18:15:50 +00002145template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002146_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002147__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002148{
Howard Hinnantc834c512011-11-29 18:15:50 +00002149 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2150 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2151 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002152}
2153
Howard Hinnantc834c512011-11-29 18:15:50 +00002154template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002155_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnantc834c512011-11-29 18:15:50 +00002156__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002157{
Howard Hinnantc834c512011-11-29 18:15:50 +00002158 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2159 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2160 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2161 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002162}
2163
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002164#ifndef _LIBCPP_CXX03_LANG
2165
Howard Hinnantc834c512011-11-29 18:15:50 +00002166template <class _Fp, class... _Args>
Louis Dionne3b967d02019-12-10 18:00:42 -05002167class _LIBCPP_HIDDEN __async_func
Howard Hinnant95cfd872011-05-19 15:05:04 +00002168{
Howard Hinnantc834c512011-11-29 18:15:50 +00002169 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002170
2171public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002172 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002173
2174 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002175 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002176 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002177
2178 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002179 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002180
Howard Hinnantc834c512011-11-29 18:15:50 +00002181 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002182 {
2183 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2184 return __execute(_Index());
2185 }
2186private:
2187 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002188 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002189 __execute(__tuple_indices<_Indices...>)
2190 {
Arthur O'Dwyer34465da2020-12-15 19:32:29 -05002191 return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002192 }
2193};
2194
Marshall Clowd56a5b62013-11-03 22:06:53 +00002195inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002196{ return (int(__policy) & int(__value)) != 0; }
2197
Howard Hinnantc834c512011-11-29 18:15:50 +00002198template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002199_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002200future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2201async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002202{
Howard Hinnantc834c512011-11-29 18:15:50 +00002203 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2204 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002205
2206#ifndef _LIBCPP_NO_EXCEPTIONS
2207 try
2208 {
2209#endif
2210 if (__does_policy_contain(__policy, launch::async))
Arthur O'Dwyer423e14b2021-12-13 19:21:38 -05002211 return _VSTD::__make_async_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
2212 _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002213#ifndef _LIBCPP_NO_EXCEPTIONS
2214 }
2215 catch ( ... ) { if (__policy == launch::async) throw ; }
2216#endif
2217
2218 if (__does_policy_contain(__policy, launch::deferred))
Arthur O'Dwyer423e14b2021-12-13 19:21:38 -05002219 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)),
2220 _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002221 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002222}
2223
Howard Hinnantc834c512011-11-29 18:15:50 +00002224template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002225_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002226future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2227async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002228{
Howard Hinnantc834c512011-11-29 18:15:50 +00002229 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002230 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002231}
2232
Louis Dionne1a1fc9d2020-07-30 10:00:53 -04002233#endif // C++03
Howard Hinnantccdd2032010-08-30 18:46:21 +00002234
Howard Hinnante6a10852010-09-03 21:46:37 +00002235// shared_future
2236
Howard Hinnantc834c512011-11-29 18:15:50 +00002237template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002238class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002239{
Howard Hinnantc834c512011-11-29 18:15:50 +00002240 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002241
2242public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002243 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002244 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002245 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002246 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002247 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002249 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002250 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002252 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002253 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002254 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002255 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant684902d2010-09-22 14:16:26 +00002256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002257 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002258 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002259 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002260 return *this;
2261 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002262
2263 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002264 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002265 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002266
Howard Hinnant684902d2010-09-22 14:16:26 +00002267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002268 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002269
2270 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002271 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002272 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002273
Howard Hinnant684902d2010-09-22 14:16:26 +00002274 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002275 void wait() const {__state_->wait();}
2276 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002277 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002278 future_status
2279 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2280 {return __state_->wait_for(__rel_time);}
2281 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002282 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002283 future_status
2284 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2285 {return __state_->wait_until(__abs_time);}
2286};
2287
Howard Hinnantc834c512011-11-29 18:15:50 +00002288template <class _Rp>
2289shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002290{
2291 if (__state_)
2292 __state_->__release_shared();
2293}
2294
Howard Hinnantc834c512011-11-29 18:15:50 +00002295template <class _Rp>
2296shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002297shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002298{
2299 if (__rhs.__state_)
2300 __rhs.__state_->__add_shared();
2301 if (__state_)
2302 __state_->__release_shared();
2303 __state_ = __rhs.__state_;
2304 return *this;
2305}
2306
Howard Hinnantc834c512011-11-29 18:15:50 +00002307template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002308class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002309{
Howard Hinnantc834c512011-11-29 18:15:50 +00002310 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002311
2312public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002314 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002316 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2317 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002319 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002320 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002322 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002323 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002324 ~shared_future();
2325 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002327 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002328 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002329 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002330 return *this;
2331 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002332
2333 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002335 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002336
Howard Hinnant684902d2010-09-22 14:16:26 +00002337 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002338 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002339
2340 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002341 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002342 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002343
Howard Hinnant684902d2010-09-22 14:16:26 +00002344 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002345 void wait() const {__state_->wait();}
2346 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002347 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002348 future_status
2349 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2350 {return __state_->wait_for(__rel_time);}
2351 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002352 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002353 future_status
2354 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2355 {return __state_->wait_until(__abs_time);}
2356};
2357
Howard Hinnantc834c512011-11-29 18:15:50 +00002358template <class _Rp>
2359shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002360{
2361 if (__state_)
2362 __state_->__release_shared();
2363}
2364
Howard Hinnantc834c512011-11-29 18:15:50 +00002365template <class _Rp>
2366shared_future<_Rp&>&
2367shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002368{
2369 if (__rhs.__state_)
2370 __rhs.__state_->__add_shared();
2371 if (__state_)
2372 __state_->__release_shared();
2373 __state_ = __rhs.__state_;
2374 return *this;
2375}
2376
2377template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002378class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002379{
2380 __assoc_sub_state* __state_;
2381
2382public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002384 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002386 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2387 {if (__state_) __state_->__add_shared();}
Howard Hinnant684902d2010-09-22 14:16:26 +00002388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002389 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002390 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002392 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002393 {__rhs.__state_ = nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002394 ~shared_future();
2395 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant684902d2010-09-22 14:16:26 +00002396 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002397 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002398 {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05002399 shared_future(_VSTD::move(__rhs)).swap(*this);
Howard Hinnant92646c42010-09-03 18:39:25 +00002400 return *this;
2401 }
Howard Hinnant92646c42010-09-03 18:39:25 +00002402
2403 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002405 void get() const {__state_->copy();}
2406
Howard Hinnant684902d2010-09-22 14:16:26 +00002407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002408 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002409
2410 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002412 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002413
Howard Hinnant684902d2010-09-22 14:16:26 +00002414 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002415 void wait() const {__state_->wait();}
2416 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002418 future_status
2419 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2420 {return __state_->wait_for(__rel_time);}
2421 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002422 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002423 future_status
2424 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2425 {return __state_->wait_until(__abs_time);}
2426};
2427
Howard Hinnantc834c512011-11-29 18:15:50 +00002428template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002429inline _LIBCPP_INLINE_VISIBILITY
2430void
Howard Hinnant22448042012-07-21 17:46:55 +00002431swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002432{
2433 __x.swap(__y);
2434}
2435
Howard Hinnantc834c512011-11-29 18:15:50 +00002436template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002437inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002438shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002439future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002440{
Howard Hinnantc834c512011-11-29 18:15:50 +00002441 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002442}
2443
Howard Hinnantc834c512011-11-29 18:15:50 +00002444template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002445inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002446shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002447future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002448{
Howard Hinnantc834c512011-11-29 18:15:50 +00002449 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002450}
2451
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002452inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002453shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002454future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002455{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002456 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002457}
2458
Howard Hinnantc51e1022010-05-11 19:42:16 +00002459_LIBCPP_END_NAMESPACE_STD
2460
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002461#endif // !_LIBCPP_HAS_NO_THREADS
2462
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002463#endif // _LIBCPP_FUTURE