blob: 6d437a489cad3c107c731e05a63c19903a6671b4 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUTURE
11#define _LIBCPP_FUTURE
12
13/*
14 future synopsis
15
16namespace std
17{
18
19enum class future_errc
20{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000021 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000022 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000023 no_state,
24 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000025};
26
27enum class launch
28{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000029 async = 1,
30 deferred = 2,
31 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000032};
33
34enum class future_status
35{
36 ready,
37 timeout,
38 deferred
39};
40
41template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000042error_code make_error_code(future_errc e) noexcept;
43error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000044
Howard Hinnant22448042012-07-21 17:46:55 +000045const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000046
47class future_error
48 : public logic_error
49{
50public:
51 future_error(error_code ec); // exposition only
Marshall Clowd4a669c2016-11-14 18:56:24 +000052 explicit future_error(future_errc); // C++17
Howard Hinnant22448042012-07-21 17:46:55 +000053 const error_code& code() const noexcept;
54 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000055};
56
57template <class R>
58class promise
59{
60public:
61 promise();
62 template <class Allocator>
63 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000064 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000065 promise(const promise& rhs) = delete;
66 ~promise();
67
68 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000069 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000070 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000071 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000072
73 // retrieving the result
74 future<R> get_future();
75
76 // setting the result
77 void set_value(const R& r);
78 void set_value(R&& r);
79 void set_exception(exception_ptr p);
80
81 // setting the result with deferred notification
82 void set_value_at_thread_exit(const R& r);
83 void set_value_at_thread_exit(R&& r);
84 void set_exception_at_thread_exit(exception_ptr p);
85};
86
87template <class R>
88class promise<R&>
89{
90public:
91 promise();
92 template <class Allocator>
93 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000094 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000095 promise(const promise& rhs) = delete;
96 ~promise();
97
98 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000099 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000100 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000101 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000102
103 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000104 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000105
106 // setting the result
107 void set_value(R& r);
108 void set_exception(exception_ptr p);
109
110 // setting the result with deferred notification
111 void set_value_at_thread_exit(R&);
112 void set_exception_at_thread_exit(exception_ptr p);
113};
114
115template <>
116class promise<void>
117{
118public:
119 promise();
120 template <class Allocator>
121 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000122 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000123 promise(const promise& rhs) = delete;
124 ~promise();
125
126 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000127 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000128 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000129 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000130
131 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000132 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000133
134 // setting the result
135 void set_value();
136 void set_exception(exception_ptr p);
137
138 // setting the result with deferred notification
139 void set_value_at_thread_exit();
140 void set_exception_at_thread_exit(exception_ptr p);
141};
142
Howard Hinnant22448042012-07-21 17:46:55 +0000143template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000144
145template <class R, class Alloc>
146 struct uses_allocator<promise<R>, Alloc> : public true_type {};
147
148template <class R>
149class future
150{
151public:
Howard Hinnant22448042012-07-21 17:46:55 +0000152 future() noexcept;
153 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000154 future(const future& rhs) = delete;
155 ~future();
156 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000157 future& operator=(future&&) noexcept;
Marshall Clow597881d2017-01-25 20:14:03 +0000158 shared_future<R> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000159
160 // retrieving the value
161 R get();
162
163 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000164 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000165
166 void wait() const;
167 template <class Rep, class Period>
168 future_status
169 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
170 template <class Clock, class Duration>
171 future_status
172 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
173};
174
175template <class R>
176class future<R&>
177{
178public:
Howard Hinnant22448042012-07-21 17:46:55 +0000179 future() noexcept;
180 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000181 future(const future& rhs) = delete;
182 ~future();
183 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000184 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000185 shared_future<R&> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000186
187 // retrieving the value
188 R& get();
189
190 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000191 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000192
193 void wait() const;
194 template <class Rep, class Period>
195 future_status
196 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
197 template <class Clock, class Duration>
198 future_status
199 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
200};
201
202template <>
203class future<void>
204{
205public:
Howard Hinnant22448042012-07-21 17:46:55 +0000206 future() noexcept;
207 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000208 future(const future& rhs) = delete;
209 ~future();
210 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000211 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000212 shared_future<void> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000213
214 // retrieving the value
215 void get();
216
217 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000218 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000219
220 void wait() const;
221 template <class Rep, class Period>
222 future_status
223 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
224 template <class Clock, class Duration>
225 future_status
226 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
227};
228
229template <class R>
230class shared_future
231{
232public:
Howard Hinnant22448042012-07-21 17:46:55 +0000233 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000234 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000235 shared_future(future<R>&&) noexcept;
236 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000237 ~shared_future();
238 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000239 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000240
241 // retrieving the value
242 const R& get() const;
243
244 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000245 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246
247 void wait() const;
248 template <class Rep, class Period>
249 future_status
250 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
251 template <class Clock, class Duration>
252 future_status
253 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
254};
255
256template <class R>
257class shared_future<R&>
258{
259public:
Howard Hinnant22448042012-07-21 17:46:55 +0000260 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000261 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000262 shared_future(future<R&>&&) noexcept;
263 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264 ~shared_future();
265 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000266 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000267
268 // retrieving the value
269 R& get() const;
270
271 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000272 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000273
274 void wait() const;
275 template <class Rep, class Period>
276 future_status
277 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
278 template <class Clock, class Duration>
279 future_status
280 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
281};
282
283template <>
284class shared_future<void>
285{
286public:
Howard Hinnant22448042012-07-21 17:46:55 +0000287 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000288 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000289 shared_future(future<void>&&) noexcept;
290 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000291 ~shared_future();
292 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000293 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000294
295 // retrieving the value
296 void get() const;
297
298 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000299 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000300
301 void wait() const;
302 template <class Rep, class Period>
303 future_status
304 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
305 template <class Clock, class Duration>
306 future_status
307 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
308};
309
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000311 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000312 async(F&& f, Args&&... args);
313
314template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000315 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000316 async(launch policy, F&& f, Args&&... args);
317
Howard Hinnantc566dc32010-05-11 21:36:01 +0000318template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000319
320template <class R, class... ArgTypes>
321class packaged_task<R(ArgTypes...)>
322{
323public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +0000324 typedef R result_type; // extension
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325
326 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000327 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000328 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 explicit packaged_task(F&& f);
Marshall Clowa0a057e2017-11-27 20:47:54 +0000330 template <class F, class Allocator>
331 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332 ~packaged_task();
333
334 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000335 packaged_task(const packaged_task&) = delete;
336 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337
338 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000339 packaged_task(packaged_task&& other) noexcept;
340 packaged_task& operator=(packaged_task&& other) noexcept;
341 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000342
Howard Hinnant22448042012-07-21 17:46:55 +0000343 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344
345 // result retrieval
346 future<R> get_future();
347
348 // execution
349 void operator()(ArgTypes... );
350 void make_ready_at_thread_exit(ArgTypes...);
351
352 void reset();
353};
354
355template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000356 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000357
Marshall Clowa0a057e2017-11-27 20:47:54 +0000358template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
359
Howard Hinnantc51e1022010-05-11 19:42:16 +0000360} // std
361
362*/
363
364#include <__config>
365#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000366#include <memory>
367#include <chrono>
368#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000369#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000370#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000371
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000372#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000373#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000374#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000375
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000376#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000377#error <future> is not supported on this single threaded system
378#else // !_LIBCPP_HAS_NO_THREADS
379
Howard Hinnantc51e1022010-05-11 19:42:16 +0000380_LIBCPP_BEGIN_NAMESPACE_STD
381
382//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000383_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000384{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000385 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000387 no_state,
388 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000389};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000390_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000391
Howard Hinnant684902d2010-09-22 14:16:26 +0000392template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000393struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000394
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000395#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
396template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000397struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000398#endif
399
Howard Hinnantc51e1022010-05-11 19:42:16 +0000400//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000401_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000402{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000403 async = 1,
404 deferred = 2,
405 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000406};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000407_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000408
Howard Hinnantda760a82013-06-29 18:38:17 +0000409#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
410
Howard Hinnantda760a82013-06-29 18:38:17 +0000411typedef underlying_type<launch>::type __launch_underlying_type;
Howard Hinnantda760a82013-06-29 18:38:17 +0000412
413inline _LIBCPP_INLINE_VISIBILITY
414_LIBCPP_CONSTEXPR
415launch
416operator&(launch __x, launch __y)
417{
418 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
419 static_cast<__launch_underlying_type>(__y));
420}
421
422inline _LIBCPP_INLINE_VISIBILITY
423_LIBCPP_CONSTEXPR
424launch
425operator|(launch __x, launch __y)
426{
427 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
428 static_cast<__launch_underlying_type>(__y));
429}
430
431inline _LIBCPP_INLINE_VISIBILITY
432_LIBCPP_CONSTEXPR
433launch
434operator^(launch __x, launch __y)
435{
436 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
437 static_cast<__launch_underlying_type>(__y));
438}
439
440inline _LIBCPP_INLINE_VISIBILITY
441_LIBCPP_CONSTEXPR
442launch
443operator~(launch __x)
444{
Howard Hinnant373d7602013-07-02 18:01:41 +0000445 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000446}
447
448inline _LIBCPP_INLINE_VISIBILITY
449launch&
450operator&=(launch& __x, launch __y)
451{
452 __x = __x & __y; return __x;
453}
454
455inline _LIBCPP_INLINE_VISIBILITY
456launch&
457operator|=(launch& __x, launch __y)
458{
459 __x = __x | __y; return __x;
460}
461
462inline _LIBCPP_INLINE_VISIBILITY
463launch&
464operator^=(launch& __x, launch __y)
465{
466 __x = __x ^ __y; return __x;
467}
468
469#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
470
Howard Hinnantc51e1022010-05-11 19:42:16 +0000471//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000472_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000473{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474 ready,
475 timeout,
476 deferred
477};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000478_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479
Howard Hinnant8331b762013-03-06 23:30:19 +0000480_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000481const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000482
483inline _LIBCPP_INLINE_VISIBILITY
484error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000485make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000486{
487 return error_code(static_cast<int>(__e), future_category());
488}
489
490inline _LIBCPP_INLINE_VISIBILITY
491error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000492make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000493{
494 return error_condition(static_cast<int>(__e), future_category());
495}
496
Mehdi Amini228053d2017-05-04 17:08:54 +0000497class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000498 : public logic_error
499{
500 error_code __ec_;
501public:
502 future_error(error_code __ec);
Marshall Clowd4a669c2016-11-14 18:56:24 +0000503#if _LIBCPP_STD_VERS > 14
504 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
505#endif
Howard Hinnant684902d2010-09-22 14:16:26 +0000506 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000507 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000508
Dimitry Andric47269ce2020-03-13 19:36:26 +0100509 future_error(const future_error&) _NOEXCEPT = default;
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000510 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000511};
512
Louis Dionne16fe2952018-07-11 23:14:33 +0000513_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000514#ifndef _LIBCPP_NO_EXCEPTIONS
515_LIBCPP_AVAILABILITY_FUTURE_ERROR
516#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000517void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000518{
519#ifndef _LIBCPP_NO_EXCEPTIONS
520 throw future_error(make_error_code(_Ev));
521#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000522 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000523 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000524#endif
525}
526
Mehdi Amini228053d2017-05-04 17:08:54 +0000527class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000528 : public __shared_count
529{
530protected:
531 exception_ptr __exception_;
532 mutable mutex __mut_;
533 mutable condition_variable __cv_;
534 unsigned __state_;
535
Howard Hinnant719bda32011-05-28 14:41:13 +0000536 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000537 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000538public:
539 enum
540 {
541 __constructed = 1,
542 __future_attached = 2,
543 ready = 4,
544 deferred = 8
545 };
546
Howard Hinnant684902d2010-09-22 14:16:26 +0000547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000548 __assoc_sub_state() : __state_(0) {}
549
Howard Hinnant684902d2010-09-22 14:16:26 +0000550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000551 bool __has_value() const
552 {return (__state_ & __constructed) || (__exception_ != nullptr);}
553
Howard Hinnant684902d2010-09-22 14:16:26 +0000554 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000555 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000556 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000557 bool __has_future_attached = (__state_ & __future_attached) != 0;
558 if (__has_future_attached)
559 __throw_future_error(future_errc::future_already_retrieved);
560 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000561 __state_ |= __future_attached;
562 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000563
Howard Hinnant684902d2010-09-22 14:16:26 +0000564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000565 void __set_deferred() {__state_ |= deferred;}
566
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000568 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000569 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000570
571 void set_value();
572 void set_value_at_thread_exit();
573
574 void set_exception(exception_ptr __p);
575 void set_exception_at_thread_exit(exception_ptr __p);
576
577 void copy();
578
Howard Hinnantccdd2032010-08-30 18:46:21 +0000579 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000580 template <class _Rep, class _Period>
581 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000583 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
584 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000585 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000586 future_status
587 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000588
589 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000590};
591
Howard Hinnantf4712b92010-08-28 21:01:06 +0000592template <class _Clock, class _Duration>
593future_status
594__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
595{
596 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000597 if (__state_ & deferred)
598 return future_status::deferred;
599 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000600 __cv_.wait_until(__lk, __abs_time);
601 if (__state_ & ready)
602 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000603 return future_status::timeout;
604}
605
606template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000607inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000608future_status
609__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
610{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000611 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000612}
613
Howard Hinnantc834c512011-11-29 18:15:50 +0000614template <class _Rp>
Louis Dionne3b967d02019-12-10 18:00:42 -0500615class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000616 : public __assoc_sub_state
617{
618 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000619 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000621 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000622
Howard Hinnant719bda32011-05-28 14:41:13 +0000623 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000624public:
625
626 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000627#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000628 void set_value(_Arg&& __arg);
629#else
630 void set_value(_Arg& __arg);
631#endif
632
633 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000634#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000635 void set_value_at_thread_exit(_Arg&& __arg);
636#else
637 void set_value_at_thread_exit(_Arg& __arg);
638#endif
639
Howard Hinnantc834c512011-11-29 18:15:50 +0000640 _Rp move();
641 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000642};
643
Howard Hinnantc834c512011-11-29 18:15:50 +0000644template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000645void
Howard Hinnantc834c512011-11-29 18:15:50 +0000646__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000647{
648 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000649 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000650 delete this;
651}
652
Howard Hinnantc834c512011-11-29 18:15:50 +0000653template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000654template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000655_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000656void
Howard Hinnant74279a52010-09-04 23:28:19 +0000657#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000658__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000659#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000660__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000661#endif
662{
663 unique_lock<mutex> __lk(this->__mut_);
664 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000665 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000666 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000667 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000668 __cv_.notify_all();
669}
670
Howard Hinnantc834c512011-11-29 18:15:50 +0000671template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000672template <class _Arg>
673void
Howard Hinnant74279a52010-09-04 23:28:19 +0000674#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000675__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000676#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000677__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000678#endif
679{
680 unique_lock<mutex> __lk(this->__mut_);
681 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000682 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000683 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000684 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000685 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000686}
687
Howard Hinnantc834c512011-11-29 18:15:50 +0000688template <class _Rp>
689_Rp
690__assoc_state<_Rp>::move()
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 _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000697}
698
Howard Hinnantc834c512011-11-29 18:15:50 +0000699template <class _Rp>
700typename add_lvalue_reference<_Rp>::type
701__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000702{
703 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000704 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000705 if (this->__exception_ != nullptr)
706 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000707 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000708}
709
Howard Hinnantc834c512011-11-29 18:15:50 +0000710template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000711class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000712 : public __assoc_sub_state
713{
714 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000715 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000716protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000717 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000718
Howard Hinnant719bda32011-05-28 14:41:13 +0000719 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000720public:
721
Howard Hinnantc834c512011-11-29 18:15:50 +0000722 void set_value(_Rp& __arg);
723 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000724
Howard Hinnantc834c512011-11-29 18:15:50 +0000725 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000726};
727
Howard Hinnantc834c512011-11-29 18:15:50 +0000728template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000729void
Howard Hinnantc834c512011-11-29 18:15:50 +0000730__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000731{
732 delete this;
733}
734
Howard Hinnantc834c512011-11-29 18:15:50 +0000735template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000736void
Howard Hinnantc834c512011-11-29 18:15:50 +0000737__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000738{
739 unique_lock<mutex> __lk(this->__mut_);
740 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000741 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000742 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000744 __cv_.notify_all();
745}
746
Howard Hinnantc834c512011-11-29 18:15:50 +0000747template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000748void
Howard Hinnantc834c512011-11-29 18:15:50 +0000749__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000750{
751 unique_lock<mutex> __lk(this->__mut_);
752 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000753 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000754 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000755 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000756 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000757}
758
Howard Hinnantc834c512011-11-29 18:15:50 +0000759template <class _Rp>
760_Rp&
761__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000762{
763 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000764 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000765 if (this->__exception_ != nullptr)
766 rethrow_exception(this->__exception_);
767 return *__value_;
768}
769
Howard Hinnantc834c512011-11-29 18:15:50 +0000770template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000771class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000772 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000773{
Howard Hinnantc834c512011-11-29 18:15:50 +0000774 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000775 _Alloc __alloc_;
776
Howard Hinnant719bda32011-05-28 14:41:13 +0000777 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000778public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000779 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000780 explicit __assoc_state_alloc(const _Alloc& __a)
781 : __alloc_(__a) {}
782};
783
Howard Hinnantc834c512011-11-29 18:15:50 +0000784template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000785void
Howard Hinnantc834c512011-11-29 18:15:50 +0000786__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000787{
788 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000789 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000790 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
791 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000792 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000793 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000794 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000795 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000796}
797
Howard Hinnantc834c512011-11-29 18:15:50 +0000798template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000799class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000800 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000801{
Howard Hinnantc834c512011-11-29 18:15:50 +0000802 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000803 _Alloc __alloc_;
804
Howard Hinnant719bda32011-05-28 14:41:13 +0000805 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000806public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000807 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000808 explicit __assoc_state_alloc(const _Alloc& __a)
809 : __alloc_(__a) {}
810};
811
Howard Hinnantc834c512011-11-29 18:15:50 +0000812template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000813void
Howard Hinnantc834c512011-11-29 18:15:50 +0000814__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000815{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000816 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
817 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000818 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000819 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000820 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000821 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000822}
823
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000824template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000825class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000826 : public __assoc_sub_state
827{
828 typedef __assoc_sub_state base;
829 _Alloc __alloc_;
830
Howard Hinnant719bda32011-05-28 14:41:13 +0000831 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000832public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000833 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000834 explicit __assoc_sub_state_alloc(const _Alloc& __a)
835 : __alloc_(__a) {}
836};
837
838template <class _Alloc>
839void
Howard Hinnant719bda32011-05-28 14:41:13 +0000840__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000841{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000842 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
843 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000844 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000845 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000846 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000847 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000848}
849
Howard Hinnantc834c512011-11-29 18:15:50 +0000850template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000851class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000852 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000853{
Howard Hinnantc834c512011-11-29 18:15:50 +0000854 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000855
Howard Hinnantc834c512011-11-29 18:15:50 +0000856 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000857
858public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000859#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000860 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000861 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000862#endif
863
864 virtual void __execute();
865};
866
Howard Hinnant74279a52010-09-04 23:28:19 +0000867#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000868
Howard Hinnantc834c512011-11-29 18:15:50 +0000869template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000870inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000871__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
872 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000873{
874 this->__set_deferred();
875}
876
Howard Hinnant74279a52010-09-04 23:28:19 +0000877#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000878
Howard Hinnantc834c512011-11-29 18:15:50 +0000879template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000880void
Howard Hinnantc834c512011-11-29 18:15:50 +0000881__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000882{
883#ifndef _LIBCPP_NO_EXCEPTIONS
884 try
885 {
886#endif // _LIBCPP_NO_EXCEPTIONS
887 this->set_value(__func_());
888#ifndef _LIBCPP_NO_EXCEPTIONS
889 }
890 catch (...)
891 {
892 this->set_exception(current_exception());
893 }
894#endif // _LIBCPP_NO_EXCEPTIONS
895}
896
Howard Hinnantc834c512011-11-29 18:15:50 +0000897template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000898class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000899 : public __assoc_sub_state
900{
901 typedef __assoc_sub_state base;
902
Howard Hinnantc834c512011-11-29 18:15:50 +0000903 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000904
905public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000906#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000907 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000908 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000909#endif
910
911 virtual void __execute();
912};
913
Howard Hinnant74279a52010-09-04 23:28:19 +0000914#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000915
Howard Hinnantc834c512011-11-29 18:15:50 +0000916template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000917inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000918__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
919 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000920{
921 this->__set_deferred();
922}
923
Howard Hinnant74279a52010-09-04 23:28:19 +0000924#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000925
Howard Hinnantc834c512011-11-29 18:15:50 +0000926template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000927void
Howard Hinnantc834c512011-11-29 18:15:50 +0000928__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000929{
930#ifndef _LIBCPP_NO_EXCEPTIONS
931 try
932 {
933#endif // _LIBCPP_NO_EXCEPTIONS
934 __func_();
935 this->set_value();
936#ifndef _LIBCPP_NO_EXCEPTIONS
937 }
938 catch (...)
939 {
940 this->set_exception(current_exception());
941 }
942#endif // _LIBCPP_NO_EXCEPTIONS
943}
944
Howard Hinnantc834c512011-11-29 18:15:50 +0000945template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000946class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000947 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000948{
Howard Hinnantc834c512011-11-29 18:15:50 +0000949 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000950
Howard Hinnantc834c512011-11-29 18:15:50 +0000951 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000952
Howard Hinnant719bda32011-05-28 14:41:13 +0000953 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000954public:
955#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000956 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000957 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000958#endif
959
960 virtual void __execute();
961};
962
963#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
964
Howard Hinnantc834c512011-11-29 18:15:50 +0000965template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000966inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000967__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
968 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000969{
970}
971
972#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
973
Howard Hinnantc834c512011-11-29 18:15:50 +0000974template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000975void
Howard Hinnantc834c512011-11-29 18:15:50 +0000976__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000977{
978#ifndef _LIBCPP_NO_EXCEPTIONS
979 try
980 {
981#endif // _LIBCPP_NO_EXCEPTIONS
982 this->set_value(__func_());
983#ifndef _LIBCPP_NO_EXCEPTIONS
984 }
985 catch (...)
986 {
987 this->set_exception(current_exception());
988 }
989#endif // _LIBCPP_NO_EXCEPTIONS
990}
991
Howard Hinnantc834c512011-11-29 18:15:50 +0000992template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000993void
Howard Hinnantc834c512011-11-29 18:15:50 +0000994__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000995{
996 this->wait();
997 base::__on_zero_shared();
998}
999
Howard Hinnantc834c512011-11-29 18:15:50 +00001000template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001001class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001002 : public __assoc_sub_state
1003{
1004 typedef __assoc_sub_state base;
1005
Howard Hinnantc834c512011-11-29 18:15:50 +00001006 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001007
Howard Hinnant719bda32011-05-28 14:41:13 +00001008 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001009public:
1010#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001012 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001013#endif
1014
1015 virtual void __execute();
1016};
1017
1018#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1019
Howard Hinnantc834c512011-11-29 18:15:50 +00001020template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001021inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001022__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1023 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001024{
1025}
1026
1027#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1028
Howard Hinnantc834c512011-11-29 18:15:50 +00001029template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001030void
Howard Hinnantc834c512011-11-29 18:15:50 +00001031__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001032{
1033#ifndef _LIBCPP_NO_EXCEPTIONS
1034 try
1035 {
1036#endif // _LIBCPP_NO_EXCEPTIONS
1037 __func_();
1038 this->set_value();
1039#ifndef _LIBCPP_NO_EXCEPTIONS
1040 }
1041 catch (...)
1042 {
1043 this->set_exception(current_exception());
1044 }
1045#endif // _LIBCPP_NO_EXCEPTIONS
1046}
1047
Howard Hinnantc834c512011-11-29 18:15:50 +00001048template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001049void
Howard Hinnantc834c512011-11-29 18:15:50 +00001050__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001051{
1052 this->wait();
1053 base::__on_zero_shared();
1054}
1055
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001056template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1057template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001058
1059// future
1060
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001061template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001062
Howard Hinnantc834c512011-11-29 18:15:50 +00001063template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001064_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001065#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001066__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001067#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001068__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001069#endif
1070
Howard Hinnantc834c512011-11-29 18:15:50 +00001071template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001072_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001073#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001074__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001075#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001076__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001077#endif
1078
Howard Hinnantc834c512011-11-29 18:15:50 +00001079template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001080class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001081{
Howard Hinnantc834c512011-11-29 18:15:50 +00001082 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001083
Howard Hinnantc834c512011-11-29 18:15:50 +00001084 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001085
1086 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001087 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001088
Howard Hinnant74279a52010-09-04 23:28:19 +00001089#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001090 template <class _R1, class _Fp>
1091 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1092 template <class _R1, class _Fp>
1093 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001094#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001095 template <class _R1, class _Fp>
1096 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1097 template <class _R1, class _Fp>
1098 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001099#endif
1100
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001101public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001102 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001103 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001104#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001105 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001106 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001107 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1108 future(const future&) = delete;
1109 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001110 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001111 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001112 {
1113 future(std::move(__rhs)).swap(*this);
1114 return *this;
1115 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001116#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001117private:
1118 future(const future&);
1119 future& operator=(const future&);
1120public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001121#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001122 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001123 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001124 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001125
1126 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001127 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001128
Howard Hinnant684902d2010-09-22 14:16:26 +00001129 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001130 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001131
1132 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001133 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001134 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001135
Howard Hinnant684902d2010-09-22 14:16:26 +00001136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001137 void wait() const {__state_->wait();}
1138 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001139 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001140 future_status
1141 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1142 {return __state_->wait_for(__rel_time);}
1143 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001144 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001145 future_status
1146 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1147 {return __state_->wait_until(__abs_time);}
1148};
1149
Howard Hinnantc834c512011-11-29 18:15:50 +00001150template <class _Rp>
1151future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001152 : __state_(__state)
1153{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001154 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001155}
1156
Howard Hinnantccdd2032010-08-30 18:46:21 +00001157struct __release_shared_count
1158{
1159 void operator()(__shared_count* p) {p->__release_shared();}
1160};
1161
Howard Hinnantc834c512011-11-29 18:15:50 +00001162template <class _Rp>
1163future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001164{
1165 if (__state_)
1166 __state_->__release_shared();
1167}
1168
Howard Hinnantc834c512011-11-29 18:15:50 +00001169template <class _Rp>
1170_Rp
1171future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001172{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001173 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001174 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001175 __state_ = nullptr;
1176 return __s->move();
1177}
1178
Howard Hinnantc834c512011-11-29 18:15:50 +00001179template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001180class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001181{
Howard Hinnantc834c512011-11-29 18:15:50 +00001182 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001183
Howard Hinnantc834c512011-11-29 18:15:50 +00001184 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001185
1186 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001187 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001188
Howard Hinnant74279a52010-09-04 23:28:19 +00001189#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001190 template <class _R1, class _Fp>
1191 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1192 template <class _R1, class _Fp>
1193 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001194#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001195 template <class _R1, class _Fp>
1196 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1197 template <class _R1, class _Fp>
1198 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001199#endif
1200
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001201public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001202 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001203 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001204#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001206 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001207 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1208 future(const future&) = delete;
1209 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001210 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001211 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001212 {
1213 future(std::move(__rhs)).swap(*this);
1214 return *this;
1215 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001216#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001217private:
1218 future(const future&);
1219 future& operator=(const future&);
1220public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001221#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001222 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001223 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001224 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001225
1226 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001227 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001228
Howard Hinnant684902d2010-09-22 14:16:26 +00001229 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001230 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001231
1232 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001234 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001235
Howard Hinnant684902d2010-09-22 14:16:26 +00001236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001237 void wait() const {__state_->wait();}
1238 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001240 future_status
1241 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1242 {return __state_->wait_for(__rel_time);}
1243 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001245 future_status
1246 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1247 {return __state_->wait_until(__abs_time);}
1248};
1249
Howard Hinnantc834c512011-11-29 18:15:50 +00001250template <class _Rp>
1251future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001252 : __state_(__state)
1253{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001254 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001255}
1256
Howard Hinnantc834c512011-11-29 18:15:50 +00001257template <class _Rp>
1258future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001259{
1260 if (__state_)
1261 __state_->__release_shared();
1262}
1263
Howard Hinnantc834c512011-11-29 18:15:50 +00001264template <class _Rp>
1265_Rp&
1266future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001267{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001268 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001269 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001270 __state_ = nullptr;
1271 return __s->copy();
1272}
1273
1274template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001275class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001276{
1277 __assoc_sub_state* __state_;
1278
1279 explicit future(__assoc_sub_state* __state);
1280
1281 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001282 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001283
Howard Hinnant74279a52010-09-04 23:28:19 +00001284#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001285 template <class _R1, class _Fp>
1286 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1287 template <class _R1, class _Fp>
1288 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001289#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001290 template <class _R1, class _Fp>
1291 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1292 template <class _R1, class _Fp>
1293 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001294#endif
1295
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001296public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001297 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001298 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001299#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001301 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001302 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1303 future(const future&) = delete;
1304 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001306 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001307 {
1308 future(std::move(__rhs)).swap(*this);
1309 return *this;
1310 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001311#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001312private:
1313 future(const future&);
1314 future& operator=(const future&);
1315public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001316#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001317 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001318 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001319 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001320
1321 // retrieving the value
1322 void get();
1323
Howard Hinnant684902d2010-09-22 14:16:26 +00001324 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001325 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001326
1327 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001328 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001329 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001330
Howard Hinnant684902d2010-09-22 14:16:26 +00001331 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001332 void wait() const {__state_->wait();}
1333 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001335 future_status
1336 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1337 {return __state_->wait_for(__rel_time);}
1338 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001340 future_status
1341 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1342 {return __state_->wait_until(__abs_time);}
1343};
1344
Howard Hinnantc834c512011-11-29 18:15:50 +00001345template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001346inline _LIBCPP_INLINE_VISIBILITY
1347void
Howard Hinnant22448042012-07-21 17:46:55 +00001348swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001349{
1350 __x.swap(__y);
1351}
1352
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001353// promise<R>
1354
Howard Hinnant944510a2011-06-14 19:58:17 +00001355template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001356
Howard Hinnantc834c512011-11-29 18:15:50 +00001357template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001358class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001359{
Howard Hinnantc834c512011-11-29 18:15:50 +00001360 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001361
Howard Hinnant684902d2010-09-22 14:16:26 +00001362 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001363 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001364
1365 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001366public:
1367 promise();
1368 template <class _Alloc>
1369 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001370#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001372 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001373 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1374 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001375#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001376private:
1377 promise(const promise& __rhs);
1378public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001379#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001380 ~promise();
1381
1382 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001383#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001385 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001386 {
1387 promise(std::move(__rhs)).swap(*this);
1388 return *this;
1389 }
1390 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001391#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001392private:
1393 promise& operator=(const promise& __rhs);
1394public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001395#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001396 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001397 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001398
1399 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001400 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001401
1402 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001403 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001404#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001405 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001406#endif
1407 void set_exception(exception_ptr __p);
1408
1409 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001410 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001411#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001412 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001413#endif
1414 void set_exception_at_thread_exit(exception_ptr __p);
1415};
1416
Howard Hinnantc834c512011-11-29 18:15:50 +00001417template <class _Rp>
1418promise<_Rp>::promise()
1419 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001420{
1421}
1422
Howard Hinnantc834c512011-11-29 18:15:50 +00001423template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001424template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001425promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001426{
Eric Fiselier0d109272014-10-23 06:24:45 +00001427 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1428 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001429 typedef __allocator_destructor<_A2> _D2;
1430 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001431 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1432 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1433 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001434}
1435
Howard Hinnantc834c512011-11-29 18:15:50 +00001436template <class _Rp>
1437promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001438{
1439 if (__state_)
1440 {
1441 if (!__state_->__has_value() && __state_->use_count() > 1)
1442 __state_->set_exception(make_exception_ptr(
1443 future_error(make_error_code(future_errc::broken_promise))
1444 ));
1445 __state_->__release_shared();
1446 }
1447}
1448
Howard Hinnantc834c512011-11-29 18:15:50 +00001449template <class _Rp>
1450future<_Rp>
1451promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001452{
1453 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001454 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001455 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001456}
1457
Howard Hinnantc834c512011-11-29 18:15:50 +00001458template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001459void
Howard Hinnantc834c512011-11-29 18:15:50 +00001460promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001461{
1462 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001463 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001464 __state_->set_value(__r);
1465}
1466
Howard Hinnant74279a52010-09-04 23:28:19 +00001467#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001468
Howard Hinnantc834c512011-11-29 18:15:50 +00001469template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001470void
Howard Hinnantc834c512011-11-29 18:15:50 +00001471promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001472{
1473 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001474 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001475 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001476}
1477
Howard Hinnant74279a52010-09-04 23:28:19 +00001478#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001479
Howard Hinnantc834c512011-11-29 18:15:50 +00001480template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001481void
Howard Hinnantc834c512011-11-29 18:15:50 +00001482promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001483{
Marshall Clow2b36f572016-05-16 16:55:32 +00001484 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001485 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001486 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001487 __state_->set_exception(__p);
1488}
1489
Howard Hinnantc834c512011-11-29 18:15:50 +00001490template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001491void
Howard Hinnantc834c512011-11-29 18:15:50 +00001492promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001493{
1494 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001495 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001496 __state_->set_value_at_thread_exit(__r);
1497}
1498
Howard Hinnant74279a52010-09-04 23:28:19 +00001499#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001500
Howard Hinnantc834c512011-11-29 18:15:50 +00001501template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001502void
Howard Hinnantc834c512011-11-29 18:15:50 +00001503promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504{
1505 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001506 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001507 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001508}
1509
Howard Hinnant74279a52010-09-04 23:28:19 +00001510#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001511
Howard Hinnantc834c512011-11-29 18:15:50 +00001512template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001513void
Howard Hinnantc834c512011-11-29 18:15:50 +00001514promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001515{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001516 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001517 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001518 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001519 __state_->set_exception_at_thread_exit(__p);
1520}
1521
1522// promise<R&>
1523
Howard Hinnantc834c512011-11-29 18:15:50 +00001524template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001525class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001526{
Howard Hinnantc834c512011-11-29 18:15:50 +00001527 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001528
Howard Hinnant684902d2010-09-22 14:16:26 +00001529 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001530 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001531
1532 template <class> friend class packaged_task;
1533
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001534public:
1535 promise();
1536 template <class _Allocator>
1537 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001538#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001540 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001541 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1542 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001543#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001544private:
1545 promise(const promise& __rhs);
1546public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001547#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001548 ~promise();
1549
1550 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001551#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001553 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001554 {
1555 promise(std::move(__rhs)).swap(*this);
1556 return *this;
1557 }
1558 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001559#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001560private:
1561 promise& operator=(const promise& __rhs);
1562public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001563#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001565 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001566
1567 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001568 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001569
1570 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001571 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001572 void set_exception(exception_ptr __p);
1573
1574 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001575 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001576 void set_exception_at_thread_exit(exception_ptr __p);
1577};
1578
Howard Hinnantc834c512011-11-29 18:15:50 +00001579template <class _Rp>
1580promise<_Rp&>::promise()
1581 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001582{
1583}
1584
Howard Hinnantc834c512011-11-29 18:15:50 +00001585template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001586template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001587promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001588{
Eric Fiselier0d109272014-10-23 06:24:45 +00001589 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1590 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001591 typedef __allocator_destructor<_A2> _D2;
1592 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001593 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1594 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1595 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001596}
1597
Howard Hinnantc834c512011-11-29 18:15:50 +00001598template <class _Rp>
1599promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001600{
1601 if (__state_)
1602 {
1603 if (!__state_->__has_value() && __state_->use_count() > 1)
1604 __state_->set_exception(make_exception_ptr(
1605 future_error(make_error_code(future_errc::broken_promise))
1606 ));
1607 __state_->__release_shared();
1608 }
1609}
1610
Howard Hinnantc834c512011-11-29 18:15:50 +00001611template <class _Rp>
1612future<_Rp&>
1613promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001614{
1615 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001616 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001617 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001618}
1619
Howard Hinnantc834c512011-11-29 18:15:50 +00001620template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001621void
Howard Hinnantc834c512011-11-29 18:15:50 +00001622promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001623{
1624 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001625 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001626 __state_->set_value(__r);
1627}
1628
Howard Hinnantc834c512011-11-29 18:15:50 +00001629template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001630void
Howard Hinnantc834c512011-11-29 18:15:50 +00001631promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001632{
Marshall Clow2b36f572016-05-16 16:55:32 +00001633 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001634 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001635 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001636 __state_->set_exception(__p);
1637}
1638
Howard Hinnantc834c512011-11-29 18:15:50 +00001639template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001640void
Howard Hinnantc834c512011-11-29 18:15:50 +00001641promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001642{
1643 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001644 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001645 __state_->set_value_at_thread_exit(__r);
1646}
1647
Howard Hinnantc834c512011-11-29 18:15:50 +00001648template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001649void
Howard Hinnantc834c512011-11-29 18:15:50 +00001650promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001651{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001652 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001653 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001654 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001655 __state_->set_exception_at_thread_exit(__p);
1656}
1657
1658// promise<void>
1659
1660template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001661class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001662{
1663 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001664
Howard Hinnant684902d2010-09-22 14:16:26 +00001665 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001666 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001667
1668 template <class> friend class packaged_task;
1669
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001670public:
1671 promise();
1672 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001673 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001674 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001675#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001676 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001677 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001678 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1679 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001680#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001681private:
1682 promise(const promise& __rhs);
1683public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001684#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001685 ~promise();
1686
1687 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001688#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001689 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001690 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001691 {
1692 promise(std::move(__rhs)).swap(*this);
1693 return *this;
1694 }
1695 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001696#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001697private:
1698 promise& operator=(const promise& __rhs);
1699public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001700#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001702 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001703
1704 // retrieving the result
1705 future<void> get_future();
1706
1707 // setting the result
1708 void set_value();
1709 void set_exception(exception_ptr __p);
1710
1711 // setting the result with deferred notification
1712 void set_value_at_thread_exit();
1713 void set_exception_at_thread_exit(exception_ptr __p);
1714};
1715
1716template <class _Alloc>
1717promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1718{
Eric Fiselier0d109272014-10-23 06:24:45 +00001719 typedef __assoc_sub_state_alloc<_Alloc> _State;
1720 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001721 typedef __allocator_destructor<_A2> _D2;
1722 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001723 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1724 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1725 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001726}
1727
Howard Hinnantc834c512011-11-29 18:15:50 +00001728template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001729inline _LIBCPP_INLINE_VISIBILITY
1730void
Howard Hinnant22448042012-07-21 17:46:55 +00001731swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001732{
1733 __x.swap(__y);
1734}
1735
Howard Hinnantc834c512011-11-29 18:15:50 +00001736template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001737 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001738 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001739
Howard Hinnantccdd2032010-08-30 18:46:21 +00001740#ifndef _LIBCPP_HAS_NO_VARIADICS
1741
1742// packaged_task
1743
1744template<class _Fp> class __packaged_task_base;
1745
Howard Hinnantc834c512011-11-29 18:15:50 +00001746template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001747class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001748{
1749 __packaged_task_base(const __packaged_task_base&);
1750 __packaged_task_base& operator=(const __packaged_task_base&);
1751public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001752 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001753 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001755 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001756 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001757 virtual void destroy() = 0;
1758 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001759 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001760};
1761
1762template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1763
Howard Hinnantc834c512011-11-29 18:15:50 +00001764template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001765class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001766 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001767{
Howard Hinnantc834c512011-11-29 18:15:50 +00001768 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001769public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001770 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001771 explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001772 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier33ebfb62019-12-16 18:23:39 -05001773 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001775 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001776 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001778 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001779 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001780 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001781 virtual void destroy();
1782 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001783 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001784};
1785
Howard Hinnantc834c512011-11-29 18:15:50 +00001786template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001787void
Howard Hinnantc834c512011-11-29 18:15:50 +00001788__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001789 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001790{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001791 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001792}
1793
Howard Hinnantc834c512011-11-29 18:15:50 +00001794template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001795void
Howard Hinnantc834c512011-11-29 18:15:50 +00001796__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001797{
Howard Hinnantc834c512011-11-29 18:15:50 +00001798 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001799}
1800
Howard Hinnantc834c512011-11-29 18:15:50 +00001801template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001802void
Howard Hinnantc834c512011-11-29 18:15:50 +00001803__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001804{
Eric Fiselier0d109272014-10-23 06:24:45 +00001805 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1806 typedef allocator_traits<_Ap> _ATraits;
1807 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001808 _Ap __a(__f_.second());
1809 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001810 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001811}
1812
Howard Hinnantc834c512011-11-29 18:15:50 +00001813template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1814_Rp
1815__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001816{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001817 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001818}
1819
Howard Hinnant944510a2011-06-14 19:58:17 +00001820template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001821
Howard Hinnantc834c512011-11-29 18:15:50 +00001822template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001823class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001824{
Howard Hinnantc834c512011-11-29 18:15:50 +00001825 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001826
1827 _LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
1828 __base* __get_buf() { return (__base*)&__buf_; }
1829
Howard Hinnant022c7482013-01-21 17:26:55 +00001830 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001831 __base* __f_;
1832
1833public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001834 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001835
1836 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001837 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001838 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001839 template<class _Fp>
1840 __packaged_task_function(_Fp&& __f);
1841 template<class _Fp, class _Alloc>
1842 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001843
Howard Hinnant22448042012-07-21 17:46:55 +00001844 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1845 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001846
1847 __packaged_task_function(const __packaged_task_function&) = delete;
1848 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1849
1850 ~__packaged_task_function();
1851
Howard Hinnant22448042012-07-21 17:46:55 +00001852 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001853
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001854 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001855 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001856};
1857
Howard Hinnantc834c512011-11-29 18:15:50 +00001858template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001859__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001860{
1861 if (__f.__f_ == nullptr)
1862 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001863 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001864 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001865 __f.__f_->__move_to(__get_buf());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001866 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001867 }
1868 else
1869 {
1870 __f_ = __f.__f_;
1871 __f.__f_ = nullptr;
1872 }
1873}
1874
Howard Hinnantc834c512011-11-29 18:15:50 +00001875template<class _Rp, class ..._ArgTypes>
1876template <class _Fp>
1877__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001878 : __f_(nullptr)
1879{
Marshall Clow733d60e2014-04-07 13:32:26 +00001880 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001881 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001882 if (sizeof(_FF) <= sizeof(__buf_))
1883 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001884 ::new (&__buf_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001885 __f_ = (__base*)&__buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001886 }
1887 else
1888 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001889 typedef allocator<_FF> _Ap;
1890 _Ap __a;
1891 typedef __allocator_destructor<_Ap> _Dp;
1892 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1893 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001894 __f_ = __hold.release();
1895 }
1896}
1897
Howard Hinnantc834c512011-11-29 18:15:50 +00001898template<class _Rp, class ..._ArgTypes>
1899template <class _Fp, class _Alloc>
1900__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1901 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001902 : __f_(nullptr)
1903{
Marshall Clow733d60e2014-04-07 13:32:26 +00001904 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001905 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001906 if (sizeof(_FF) <= sizeof(__buf_))
1907 {
1908 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001909 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001910 }
1911 else
1912 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001913 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001914 _Ap __a(__a0);
1915 typedef __allocator_destructor<_Ap> _Dp;
1916 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001917 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1918 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1919 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001920 }
1921}
1922
Howard Hinnantc834c512011-11-29 18:15:50 +00001923template<class _Rp, class ..._ArgTypes>
1924__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001925__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001926{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001927 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001928 __f_->destroy();
1929 else if (__f_)
1930 __f_->destroy_deallocate();
1931 __f_ = nullptr;
1932 if (__f.__f_ == nullptr)
1933 __f_ = nullptr;
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001934 else if (__f.__f_ == __f.__get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001935 {
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001936 __f.__f_->__move_to(__get_buf());
1937 __f_ = __get_buf();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001938 }
1939 else
1940 {
1941 __f_ = __f.__f_;
1942 __f.__f_ = nullptr;
1943 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001944 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001945}
1946
Howard Hinnantc834c512011-11-29 18:15:50 +00001947template<class _Rp, class ..._ArgTypes>
1948__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001949{
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001950 if (__f_ == __get_buf())
Howard Hinnantccdd2032010-08-30 18:46:21 +00001951 __f_->destroy();
1952 else if (__f_)
1953 __f_->destroy_deallocate();
1954}
1955
Howard Hinnantc834c512011-11-29 18:15:50 +00001956template<class _Rp, class ..._ArgTypes>
Evgenii Stepanov9dd5fc22020-08-06 11:32:33 -07001957_LIBCPP_NO_CFI
Howard Hinnantccdd2032010-08-30 18:46:21 +00001958void
Howard Hinnant22448042012-07-21 17:46:55 +00001959__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001960{
1961 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1962 {
1963 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1964 __base* __t = (__base*)&__tempbuf;
1965 __f_->__move_to(__t);
1966 __f_->destroy();
1967 __f_ = nullptr;
1968 __f.__f_->__move_to((__base*)&__buf_);
1969 __f.__f_->destroy();
1970 __f.__f_ = nullptr;
1971 __f_ = (__base*)&__buf_;
1972 __t->__move_to((__base*)&__f.__buf_);
1973 __t->destroy();
1974 __f.__f_ = (__base*)&__f.__buf_;
1975 }
1976 else if (__f_ == (__base*)&__buf_)
1977 {
1978 __f_->__move_to((__base*)&__f.__buf_);
1979 __f_->destroy();
1980 __f_ = __f.__f_;
1981 __f.__f_ = (__base*)&__f.__buf_;
1982 }
1983 else if (__f.__f_ == (__base*)&__f.__buf_)
1984 {
1985 __f.__f_->__move_to((__base*)&__buf_);
1986 __f.__f_->destroy();
1987 __f.__f_ = __f_;
1988 __f_ = (__base*)&__buf_;
1989 }
1990 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001991 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001992}
1993
Howard Hinnantc834c512011-11-29 18:15:50 +00001994template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001995inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001996_Rp
1997__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001998{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001999 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002000}
2001
Howard Hinnantc834c512011-11-29 18:15:50 +00002002template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002003class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004{
2005public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002006 typedef _Rp 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
2035 >
2036 _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
Howard Hinnantc834c512011-11-29 18:15:50 +00002078template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002079void
Howard Hinnantc834c512011-11-29 18:15:50 +00002080packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081{
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 {
2089#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002090 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002091#ifndef _LIBCPP_NO_EXCEPTIONS
2092 }
2093 catch (...)
2094 {
2095 __p_.set_exception(current_exception());
2096 }
2097#endif // _LIBCPP_NO_EXCEPTIONS
2098}
2099
Howard Hinnantc834c512011-11-29 18:15:50 +00002100template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002101void
Howard Hinnantc834c512011-11-29 18:15:50 +00002102packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002103{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002104 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002105 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002106 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002107 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002108#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002109 try
2110 {
2111#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002112 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002113#ifndef _LIBCPP_NO_EXCEPTIONS
2114 }
2115 catch (...)
2116 {
2117 __p_.set_exception_at_thread_exit(current_exception());
2118 }
2119#endif // _LIBCPP_NO_EXCEPTIONS
2120}
2121
Howard Hinnantc834c512011-11-29 18:15:50 +00002122template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002123void
Howard Hinnantc834c512011-11-29 18:15:50 +00002124packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002125{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002126 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002127 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002128 __p_ = promise<result_type>();
2129}
2130
2131template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002132class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002133{
2134public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002135 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002136
2137private:
2138 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2139 promise<result_type> __p_;
2140
2141public:
2142 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002143 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002144 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002145 template <class _Fp,
2146 class = typename enable_if
2147 <
2148 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002149 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002150 packaged_task
2151 >::value
2152 >::type
2153 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002154 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002155 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002156 template <class _Fp, class _Allocator,
2157 class = typename enable_if
2158 <
2159 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002160 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002161 packaged_task
2162 >::value
2163 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002164 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002165 _LIBCPP_INLINE_VISIBILITY
2166 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2167 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2168 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002169 // ~packaged_task() = default;
2170
2171 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002172 packaged_task(const packaged_task&) = delete;
2173 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002174
2175 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002177 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002178 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002179 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002180 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002181 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002182 __f_ = _VSTD::move(__other.__f_);
2183 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002184 return *this;
2185 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002186 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002187 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002188 {
2189 __f_.swap(__other.__f_);
2190 __p_.swap(__other.__p_);
2191 }
2192
Howard Hinnant684902d2010-09-22 14:16:26 +00002193 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002194 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002195
2196 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002198 future<result_type> get_future() {return __p_.get_future();}
2199
2200 // execution
2201 void operator()(_ArgTypes... __args);
2202 void make_ready_at_thread_exit(_ArgTypes... __args);
2203
2204 void reset();
2205};
2206
2207template<class ..._ArgTypes>
2208void
2209packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2210{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002211 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002212 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002213 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002214 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002215#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002216 try
2217 {
2218#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002219 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002220 __p_.set_value();
2221#ifndef _LIBCPP_NO_EXCEPTIONS
2222 }
2223 catch (...)
2224 {
2225 __p_.set_exception(current_exception());
2226 }
2227#endif // _LIBCPP_NO_EXCEPTIONS
2228}
2229
2230template<class ..._ArgTypes>
2231void
2232packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2233{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002234 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002235 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002236 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002237 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002238#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002239 try
2240 {
2241#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002242 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002243 __p_.set_value_at_thread_exit();
2244#ifndef _LIBCPP_NO_EXCEPTIONS
2245 }
2246 catch (...)
2247 {
2248 __p_.set_exception_at_thread_exit(current_exception());
2249 }
2250#endif // _LIBCPP_NO_EXCEPTIONS
2251}
2252
2253template<class ..._ArgTypes>
2254void
2255packaged_task<void(_ArgTypes...)>::reset()
2256{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002257 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002258 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002259 __p_ = promise<result_type>();
2260}
2261
2262template <class _Callable>
2263inline _LIBCPP_INLINE_VISIBILITY
2264void
Howard Hinnant22448042012-07-21 17:46:55 +00002265swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002266{
2267 __x.swap(__y);
2268}
2269
Marshall Clowa0a057e2017-11-27 20:47:54 +00002270template <class _Callable, class _Alloc>
2271struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2272 : public true_type {};
2273
Howard Hinnantc834c512011-11-29 18:15:50 +00002274template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002275_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002276#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002277__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002278#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002279__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002280#endif
2281{
Howard Hinnantc834c512011-11-29 18:15:50 +00002282 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2283 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2284 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002285}
2286
Howard Hinnantc834c512011-11-29 18:15:50 +00002287template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002288_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002289#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002290__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002291#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002292__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002293#endif
2294{
Howard Hinnantc834c512011-11-29 18:15:50 +00002295 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2296 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2297 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2298 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002299}
2300
Howard Hinnantc834c512011-11-29 18:15:50 +00002301template <class _Fp, class... _Args>
Louis Dionne3b967d02019-12-10 18:00:42 -05002302class _LIBCPP_HIDDEN __async_func
Howard Hinnant95cfd872011-05-19 15:05:04 +00002303{
Howard Hinnantc834c512011-11-29 18:15:50 +00002304 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002305
2306public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002307 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002308
2309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002310 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002311 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002312
2313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002314 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002315
Howard Hinnantc834c512011-11-29 18:15:50 +00002316 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002317 {
2318 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2319 return __execute(_Index());
2320 }
2321private:
2322 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002323 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002324 __execute(__tuple_indices<_Indices...>)
2325 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002326 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002327 }
2328};
2329
Marshall Clowd56a5b62013-11-03 22:06:53 +00002330inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002331{ return (int(__policy) & int(__value)) != 0; }
2332
Howard Hinnantc834c512011-11-29 18:15:50 +00002333template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002334_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002335future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2336async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002337{
Howard Hinnantc834c512011-11-29 18:15:50 +00002338 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2339 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002340
2341#ifndef _LIBCPP_NO_EXCEPTIONS
2342 try
2343 {
2344#endif
2345 if (__does_policy_contain(__policy, launch::async))
2346 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002347 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002348#ifndef _LIBCPP_NO_EXCEPTIONS
2349 }
2350 catch ( ... ) { if (__policy == launch::async) throw ; }
2351#endif
2352
2353 if (__does_policy_contain(__policy, launch::deferred))
2354 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002355 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002356 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002357}
2358
Howard Hinnantc834c512011-11-29 18:15:50 +00002359template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002360_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002361future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2362async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002363{
Howard Hinnantc834c512011-11-29 18:15:50 +00002364 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002365 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002366}
2367
2368#endif // _LIBCPP_HAS_NO_VARIADICS
2369
Howard Hinnante6a10852010-09-03 21:46:37 +00002370// shared_future
2371
Howard Hinnantc834c512011-11-29 18:15:50 +00002372template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002373class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002374{
Howard Hinnantc834c512011-11-29 18:15:50 +00002375 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002376
2377public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002378 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002379 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002380 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002381 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002382 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002383#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002385 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002386 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002388 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002389 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002390#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002391 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002392 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant74279a52010-09-04 23:28:19 +00002393#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002395 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002396 {
2397 shared_future(std::move(__rhs)).swap(*this);
2398 return *this;
2399 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002400#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002401
2402 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002403 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002404 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002405
Howard Hinnant684902d2010-09-22 14:16:26 +00002406 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002407 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002408
2409 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002411 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002412
Howard Hinnant684902d2010-09-22 14:16:26 +00002413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002414 void wait() const {__state_->wait();}
2415 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002417 future_status
2418 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2419 {return __state_->wait_for(__rel_time);}
2420 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002422 future_status
2423 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2424 {return __state_->wait_until(__abs_time);}
2425};
2426
Howard Hinnantc834c512011-11-29 18:15:50 +00002427template <class _Rp>
2428shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002429{
2430 if (__state_)
2431 __state_->__release_shared();
2432}
2433
Howard Hinnantc834c512011-11-29 18:15:50 +00002434template <class _Rp>
2435shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002436shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002437{
2438 if (__rhs.__state_)
2439 __rhs.__state_->__add_shared();
2440 if (__state_)
2441 __state_->__release_shared();
2442 __state_ = __rhs.__state_;
2443 return *this;
2444}
2445
Howard Hinnantc834c512011-11-29 18:15:50 +00002446template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002447class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002448{
Howard Hinnantc834c512011-11-29 18:15:50 +00002449 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002450
2451public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002453 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002454 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002455 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2456 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002457#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002459 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002460 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002461 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002462 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002463 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002464#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002465 ~shared_future();
2466 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002467#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002469 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002470 {
2471 shared_future(std::move(__rhs)).swap(*this);
2472 return *this;
2473 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002474#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002475
2476 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002478 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002479
Howard Hinnant684902d2010-09-22 14:16:26 +00002480 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002481 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002482
2483 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002485 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002486
Howard Hinnant684902d2010-09-22 14:16:26 +00002487 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002488 void wait() const {__state_->wait();}
2489 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002490 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002491 future_status
2492 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2493 {return __state_->wait_for(__rel_time);}
2494 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002495 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002496 future_status
2497 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2498 {return __state_->wait_until(__abs_time);}
2499};
2500
Howard Hinnantc834c512011-11-29 18:15:50 +00002501template <class _Rp>
2502shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002503{
2504 if (__state_)
2505 __state_->__release_shared();
2506}
2507
Howard Hinnantc834c512011-11-29 18:15:50 +00002508template <class _Rp>
2509shared_future<_Rp&>&
2510shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002511{
2512 if (__rhs.__state_)
2513 __rhs.__state_->__add_shared();
2514 if (__state_)
2515 __state_->__release_shared();
2516 __state_ = __rhs.__state_;
2517 return *this;
2518}
2519
2520template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002521class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002522{
2523 __assoc_sub_state* __state_;
2524
2525public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002527 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002529 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2530 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002531#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002533 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002534 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002536 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002537 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002538#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002539 ~shared_future();
2540 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002541#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002543 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002544 {
2545 shared_future(std::move(__rhs)).swap(*this);
2546 return *this;
2547 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002548#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002549
2550 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002552 void get() const {__state_->copy();}
2553
Howard Hinnant684902d2010-09-22 14:16:26 +00002554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002555 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002556
2557 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002559 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002560
Howard Hinnant684902d2010-09-22 14:16:26 +00002561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002562 void wait() const {__state_->wait();}
2563 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002565 future_status
2566 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2567 {return __state_->wait_for(__rel_time);}
2568 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002569 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002570 future_status
2571 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2572 {return __state_->wait_until(__abs_time);}
2573};
2574
Howard Hinnantc834c512011-11-29 18:15:50 +00002575template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002576inline _LIBCPP_INLINE_VISIBILITY
2577void
Howard Hinnant22448042012-07-21 17:46:55 +00002578swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002579{
2580 __x.swap(__y);
2581}
2582
Howard Hinnantc834c512011-11-29 18:15:50 +00002583template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002584inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002585shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002586future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002587{
Howard Hinnantc834c512011-11-29 18:15:50 +00002588 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002589}
2590
Howard Hinnantc834c512011-11-29 18:15:50 +00002591template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002592inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002593shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002594future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002595{
Howard Hinnantc834c512011-11-29 18:15:50 +00002596 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002597}
2598
Howard Hinnante65e8e32010-12-02 16:45:21 +00002599#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2600
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002601inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002602shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002603future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002604{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002605 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002606}
2607
Howard Hinnante65e8e32010-12-02 16:45:21 +00002608#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2609
Howard Hinnantc51e1022010-05-11 19:42:16 +00002610_LIBCPP_END_NAMESPACE_STD
2611
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002612#endif // !_LIBCPP_HAS_NO_THREADS
2613
Howard Hinnantc51e1022010-05-11 19:42:16 +00002614#endif // _LIBCPP_FUTURE