blob: b3ffc7e35177fee5e5371d1becdfb1d527d94b67 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
Howard Hinnantee11c312010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc51e1022010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000022 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000023 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000024 no_state,
25 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000026};
27
28enum class launch
29{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000033};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000045
Howard Hinnant22448042012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
Marshall Clowd4a669c2016-11-14 18:56:24 +000053 explicit future_error(future_errc); // C++17
Howard Hinnant22448042012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000056};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000073
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
Howard Hinnant22448042012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
Howard Hinnant22448042012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
Marshall Clow597881d2017-01-25 20:14:03 +0000159 shared_future<R> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
Howard Hinnant22448042012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000186 shared_future<R&> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
Howard Hinnant22448042012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000213 shared_future<void> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
Howard Hinnant22448042012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
Howard Hinnant22448042012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
Howard Hinnant22448042012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantc51e1022010-05-11 19:42:16 +0000311template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000312 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000316 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantc566dc32010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +0000325 typedef R result_type; // extension
Howard Hinnantc51e1022010-05-11 19:42:16 +0000326
327 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
Marshall Clowa0a057e2017-11-27 20:47:54 +0000331 template <class F, class Allocator>
332 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000333 ~packaged_task();
334
335 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000340 packaged_task(packaged_task&& other) noexcept;
341 packaged_task& operator=(packaged_task&& other) noexcept;
342 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000343
Howard Hinnant22448042012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000358
Marshall Clowa0a057e2017-11-27 20:47:54 +0000359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
Howard Hinnantc51e1022010-05-11 19:42:16 +0000361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000375#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000377#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000378#error <future> is not supported on this single threaded system
379#else // !_LIBCPP_HAS_NO_THREADS
380
Howard Hinnantc51e1022010-05-11 19:42:16 +0000381_LIBCPP_BEGIN_NAMESPACE_STD
382
383//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000384_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000385{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000386 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000388 no_state,
389 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000391_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000392
Howard Hinnant684902d2010-09-22 14:16:26 +0000393template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000394struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000395
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000396#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000398struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000399#endif
400
Howard Hinnantc51e1022010-05-11 19:42:16 +0000401//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000402_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000403{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000404 async = 1,
405 deferred = 2,
406 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000409
Howard Hinnantda760a82013-06-29 18:38:17 +0000410#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411
Eric Fiselier94d23cb2018-07-24 09:15:03 +0000412#ifdef _LIBCPP_UNDERLYING_TYPE
Howard Hinnantda760a82013-06-29 18:38:17 +0000413typedef underlying_type<launch>::type __launch_underlying_type;
414#else
415typedef int __launch_underlying_type;
416#endif
417
418inline _LIBCPP_INLINE_VISIBILITY
419_LIBCPP_CONSTEXPR
420launch
421operator&(launch __x, launch __y)
422{
423 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
424 static_cast<__launch_underlying_type>(__y));
425}
426
427inline _LIBCPP_INLINE_VISIBILITY
428_LIBCPP_CONSTEXPR
429launch
430operator|(launch __x, launch __y)
431{
432 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
433 static_cast<__launch_underlying_type>(__y));
434}
435
436inline _LIBCPP_INLINE_VISIBILITY
437_LIBCPP_CONSTEXPR
438launch
439operator^(launch __x, launch __y)
440{
441 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
442 static_cast<__launch_underlying_type>(__y));
443}
444
445inline _LIBCPP_INLINE_VISIBILITY
446_LIBCPP_CONSTEXPR
447launch
448operator~(launch __x)
449{
Howard Hinnant373d7602013-07-02 18:01:41 +0000450 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000451}
452
453inline _LIBCPP_INLINE_VISIBILITY
454launch&
455operator&=(launch& __x, launch __y)
456{
457 __x = __x & __y; return __x;
458}
459
460inline _LIBCPP_INLINE_VISIBILITY
461launch&
462operator|=(launch& __x, launch __y)
463{
464 __x = __x | __y; return __x;
465}
466
467inline _LIBCPP_INLINE_VISIBILITY
468launch&
469operator^=(launch& __x, launch __y)
470{
471 __x = __x ^ __y; return __x;
472}
473
474#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
475
Howard Hinnantc51e1022010-05-11 19:42:16 +0000476//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000477_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000478{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479 ready,
480 timeout,
481 deferred
482};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000483_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000484
Howard Hinnant8331b762013-03-06 23:30:19 +0000485_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000486const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000487
488inline _LIBCPP_INLINE_VISIBILITY
489error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000490make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000491{
492 return error_code(static_cast<int>(__e), future_category());
493}
494
495inline _LIBCPP_INLINE_VISIBILITY
496error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000497make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000498{
499 return error_condition(static_cast<int>(__e), future_category());
500}
501
Mehdi Amini228053d2017-05-04 17:08:54 +0000502class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000503 : public logic_error
504{
505 error_code __ec_;
506public:
507 future_error(error_code __ec);
Marshall Clowd4a669c2016-11-14 18:56:24 +0000508#if _LIBCPP_STD_VERS > 14
509 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
510#endif
Howard Hinnant684902d2010-09-22 14:16:26 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000512 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000513
514 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000515};
516
Louis Dionne16fe2952018-07-11 23:14:33 +0000517_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000518#ifndef _LIBCPP_NO_EXCEPTIONS
519_LIBCPP_AVAILABILITY_FUTURE_ERROR
520#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000521void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000522{
523#ifndef _LIBCPP_NO_EXCEPTIONS
524 throw future_error(make_error_code(_Ev));
525#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000526 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000527 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000528#endif
529}
530
Mehdi Amini228053d2017-05-04 17:08:54 +0000531class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000532 : public __shared_count
533{
534protected:
535 exception_ptr __exception_;
536 mutable mutex __mut_;
537 mutable condition_variable __cv_;
538 unsigned __state_;
539
Howard Hinnant719bda32011-05-28 14:41:13 +0000540 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000541 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000542public:
543 enum
544 {
545 __constructed = 1,
546 __future_attached = 2,
547 ready = 4,
548 deferred = 8
549 };
550
Howard Hinnant684902d2010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000552 __assoc_sub_state() : __state_(0) {}
553
Howard Hinnant684902d2010-09-22 14:16:26 +0000554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000555 bool __has_value() const
556 {return (__state_ & __constructed) || (__exception_ != nullptr);}
557
Howard Hinnant684902d2010-09-22 14:16:26 +0000558 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000559 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000560 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000561 bool __has_future_attached = (__state_ & __future_attached) != 0;
562 if (__has_future_attached)
563 __throw_future_error(future_errc::future_already_retrieved);
564 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000565 __state_ |= __future_attached;
566 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567
Howard Hinnant684902d2010-09-22 14:16:26 +0000568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000569 void __set_deferred() {__state_ |= deferred;}
570
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000571 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000572 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000573 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000574
575 void set_value();
576 void set_value_at_thread_exit();
577
578 void set_exception(exception_ptr __p);
579 void set_exception_at_thread_exit(exception_ptr __p);
580
581 void copy();
582
Howard Hinnantccdd2032010-08-30 18:46:21 +0000583 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000584 template <class _Rep, class _Period>
585 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000587 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
588 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000589 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000590 future_status
591 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000592
593 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000594};
595
Howard Hinnantf4712b92010-08-28 21:01:06 +0000596template <class _Clock, class _Duration>
597future_status
598__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
599{
600 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000601 if (__state_ & deferred)
602 return future_status::deferred;
603 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000604 __cv_.wait_until(__lk, __abs_time);
605 if (__state_ & ready)
606 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000607 return future_status::timeout;
608}
609
610template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000611inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000612future_status
613__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
614{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000615 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000616}
617
Howard Hinnantc834c512011-11-29 18:15:50 +0000618template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000619class _LIBCPP_AVAILABILITY_FUTURE __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620 : public __assoc_sub_state
621{
622 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000623 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000624protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000625 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000626
Howard Hinnant719bda32011-05-28 14:41:13 +0000627 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000628public:
629
630 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000631#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000632 void set_value(_Arg&& __arg);
633#else
634 void set_value(_Arg& __arg);
635#endif
636
637 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000638#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000639 void set_value_at_thread_exit(_Arg&& __arg);
640#else
641 void set_value_at_thread_exit(_Arg& __arg);
642#endif
643
Howard Hinnantc834c512011-11-29 18:15:50 +0000644 _Rp move();
645 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000646};
647
Howard Hinnantc834c512011-11-29 18:15:50 +0000648template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000649void
Howard Hinnantc834c512011-11-29 18:15:50 +0000650__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000651{
652 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000653 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000654 delete this;
655}
656
Howard Hinnantc834c512011-11-29 18:15:50 +0000657template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000658template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000659_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000660void
Howard Hinnant74279a52010-09-04 23:28:19 +0000661#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000662__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000663#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000664__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000665#endif
666{
667 unique_lock<mutex> __lk(this->__mut_);
668 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000669 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000670 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000671 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000672 __cv_.notify_all();
673}
674
Howard Hinnantc834c512011-11-29 18:15:50 +0000675template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000676template <class _Arg>
677void
Howard Hinnant74279a52010-09-04 23:28:19 +0000678#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000679__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000680#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000681__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000682#endif
683{
684 unique_lock<mutex> __lk(this->__mut_);
685 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000686 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000687 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000688 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000689 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000690}
691
Howard Hinnantc834c512011-11-29 18:15:50 +0000692template <class _Rp>
693_Rp
694__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000695{
696 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000697 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000698 if (this->__exception_ != nullptr)
699 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000700 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000701}
702
Howard Hinnantc834c512011-11-29 18:15:50 +0000703template <class _Rp>
704typename add_lvalue_reference<_Rp>::type
705__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000706{
707 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000708 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000709 if (this->__exception_ != nullptr)
710 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000711 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000712}
713
Howard Hinnantc834c512011-11-29 18:15:50 +0000714template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000715class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000716 : public __assoc_sub_state
717{
718 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000719 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000720protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000721 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000722
Howard Hinnant719bda32011-05-28 14:41:13 +0000723 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000724public:
725
Howard Hinnantc834c512011-11-29 18:15:50 +0000726 void set_value(_Rp& __arg);
727 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728
Howard Hinnantc834c512011-11-29 18:15:50 +0000729 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000730};
731
Howard Hinnantc834c512011-11-29 18:15:50 +0000732template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000733void
Howard Hinnantc834c512011-11-29 18:15:50 +0000734__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000735{
736 delete this;
737}
738
Howard Hinnantc834c512011-11-29 18:15:50 +0000739template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000740void
Howard Hinnantc834c512011-11-29 18:15:50 +0000741__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000742{
743 unique_lock<mutex> __lk(this->__mut_);
744 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000745 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000746 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000747 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000748 __cv_.notify_all();
749}
750
Howard Hinnantc834c512011-11-29 18:15:50 +0000751template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000752void
Howard Hinnantc834c512011-11-29 18:15:50 +0000753__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000754{
755 unique_lock<mutex> __lk(this->__mut_);
756 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000757 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000758 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000759 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000760 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000761}
762
Howard Hinnantc834c512011-11-29 18:15:50 +0000763template <class _Rp>
764_Rp&
765__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000766{
767 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000768 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000769 if (this->__exception_ != nullptr)
770 rethrow_exception(this->__exception_);
771 return *__value_;
772}
773
Howard Hinnantc834c512011-11-29 18:15:50 +0000774template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000775class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000776 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000777{
Howard Hinnantc834c512011-11-29 18:15:50 +0000778 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000779 _Alloc __alloc_;
780
Howard Hinnant719bda32011-05-28 14:41:13 +0000781 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000782public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000784 explicit __assoc_state_alloc(const _Alloc& __a)
785 : __alloc_(__a) {}
786};
787
Howard Hinnantc834c512011-11-29 18:15:50 +0000788template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000789void
Howard Hinnantc834c512011-11-29 18:15:50 +0000790__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000791{
792 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000793 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000794 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
795 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000796 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000797 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000798 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000799 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000800}
801
Howard Hinnantc834c512011-11-29 18:15:50 +0000802template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000803class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000804 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000805{
Howard Hinnantc834c512011-11-29 18:15:50 +0000806 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000807 _Alloc __alloc_;
808
Howard Hinnant719bda32011-05-28 14:41:13 +0000809 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000810public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000811 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000812 explicit __assoc_state_alloc(const _Alloc& __a)
813 : __alloc_(__a) {}
814};
815
Howard Hinnantc834c512011-11-29 18:15:50 +0000816template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000817void
Howard Hinnantc834c512011-11-29 18:15:50 +0000818__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000819{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000820 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
821 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000822 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000823 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000824 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000825 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000826}
827
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000828template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000829class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000830 : public __assoc_sub_state
831{
832 typedef __assoc_sub_state base;
833 _Alloc __alloc_;
834
Howard Hinnant719bda32011-05-28 14:41:13 +0000835 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000836public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000837 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000838 explicit __assoc_sub_state_alloc(const _Alloc& __a)
839 : __alloc_(__a) {}
840};
841
842template <class _Alloc>
843void
Howard Hinnant719bda32011-05-28 14:41:13 +0000844__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000845{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000846 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
847 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000848 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000849 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000850 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000851 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000852}
853
Howard Hinnantc834c512011-11-29 18:15:50 +0000854template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000855class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000856 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000857{
Howard Hinnantc834c512011-11-29 18:15:50 +0000858 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000859
Howard Hinnantc834c512011-11-29 18:15:50 +0000860 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000861
862public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000863#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000864 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000865 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000866#endif
867
868 virtual void __execute();
869};
870
Howard Hinnant74279a52010-09-04 23:28:19 +0000871#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000872
Howard Hinnantc834c512011-11-29 18:15:50 +0000873template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000874inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000875__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
876 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000877{
878 this->__set_deferred();
879}
880
Howard Hinnant74279a52010-09-04 23:28:19 +0000881#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000882
Howard Hinnantc834c512011-11-29 18:15:50 +0000883template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000884void
Howard Hinnantc834c512011-11-29 18:15:50 +0000885__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000886{
887#ifndef _LIBCPP_NO_EXCEPTIONS
888 try
889 {
890#endif // _LIBCPP_NO_EXCEPTIONS
891 this->set_value(__func_());
892#ifndef _LIBCPP_NO_EXCEPTIONS
893 }
894 catch (...)
895 {
896 this->set_exception(current_exception());
897 }
898#endif // _LIBCPP_NO_EXCEPTIONS
899}
900
Howard Hinnantc834c512011-11-29 18:15:50 +0000901template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000902class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000903 : public __assoc_sub_state
904{
905 typedef __assoc_sub_state base;
906
Howard Hinnantc834c512011-11-29 18:15:50 +0000907 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000908
909public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000910#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000911 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000912 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000913#endif
914
915 virtual void __execute();
916};
917
Howard Hinnant74279a52010-09-04 23:28:19 +0000918#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000919
Howard Hinnantc834c512011-11-29 18:15:50 +0000920template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000921inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000922__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
923 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000924{
925 this->__set_deferred();
926}
927
Howard Hinnant74279a52010-09-04 23:28:19 +0000928#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000929
Howard Hinnantc834c512011-11-29 18:15:50 +0000930template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000931void
Howard Hinnantc834c512011-11-29 18:15:50 +0000932__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000933{
934#ifndef _LIBCPP_NO_EXCEPTIONS
935 try
936 {
937#endif // _LIBCPP_NO_EXCEPTIONS
938 __func_();
939 this->set_value();
940#ifndef _LIBCPP_NO_EXCEPTIONS
941 }
942 catch (...)
943 {
944 this->set_exception(current_exception());
945 }
946#endif // _LIBCPP_NO_EXCEPTIONS
947}
948
Howard Hinnantc834c512011-11-29 18:15:50 +0000949template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000950class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000951 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000952{
Howard Hinnantc834c512011-11-29 18:15:50 +0000953 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000954
Howard Hinnantc834c512011-11-29 18:15:50 +0000955 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000956
Howard Hinnant719bda32011-05-28 14:41:13 +0000957 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000958public:
959#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000960 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000961 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000962#endif
963
964 virtual void __execute();
965};
966
967#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
968
Howard Hinnantc834c512011-11-29 18:15:50 +0000969template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000970inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000971__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
972 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000973{
974}
975
976#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
977
Howard Hinnantc834c512011-11-29 18:15:50 +0000978template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000979void
Howard Hinnantc834c512011-11-29 18:15:50 +0000980__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000981{
982#ifndef _LIBCPP_NO_EXCEPTIONS
983 try
984 {
985#endif // _LIBCPP_NO_EXCEPTIONS
986 this->set_value(__func_());
987#ifndef _LIBCPP_NO_EXCEPTIONS
988 }
989 catch (...)
990 {
991 this->set_exception(current_exception());
992 }
993#endif // _LIBCPP_NO_EXCEPTIONS
994}
995
Howard Hinnantc834c512011-11-29 18:15:50 +0000996template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000997void
Howard Hinnantc834c512011-11-29 18:15:50 +0000998__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000999{
1000 this->wait();
1001 base::__on_zero_shared();
1002}
1003
Howard Hinnantc834c512011-11-29 18:15:50 +00001004template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001005class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001006 : public __assoc_sub_state
1007{
1008 typedef __assoc_sub_state base;
1009
Howard Hinnantc834c512011-11-29 18:15:50 +00001010 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001011
Howard Hinnant719bda32011-05-28 14:41:13 +00001012 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001013public:
1014#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001015 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001016 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001017#endif
1018
1019 virtual void __execute();
1020};
1021
1022#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1023
Howard Hinnantc834c512011-11-29 18:15:50 +00001024template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001025inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001026__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1027 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001028{
1029}
1030
1031#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1032
Howard Hinnantc834c512011-11-29 18:15:50 +00001033template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001034void
Howard Hinnantc834c512011-11-29 18:15:50 +00001035__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001036{
1037#ifndef _LIBCPP_NO_EXCEPTIONS
1038 try
1039 {
1040#endif // _LIBCPP_NO_EXCEPTIONS
1041 __func_();
1042 this->set_value();
1043#ifndef _LIBCPP_NO_EXCEPTIONS
1044 }
1045 catch (...)
1046 {
1047 this->set_exception(current_exception());
1048 }
1049#endif // _LIBCPP_NO_EXCEPTIONS
1050}
1051
Howard Hinnantc834c512011-11-29 18:15:50 +00001052template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001053void
Howard Hinnantc834c512011-11-29 18:15:50 +00001054__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001055{
1056 this->wait();
1057 base::__on_zero_shared();
1058}
1059
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001060template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1061template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001062
1063// future
1064
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001065template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001066
Howard Hinnantc834c512011-11-29 18:15:50 +00001067template <class _Rp, class _Fp>
1068future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001069#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001070__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001071#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001072__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001073#endif
1074
Howard Hinnantc834c512011-11-29 18:15:50 +00001075template <class _Rp, class _Fp>
1076future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001077#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001078__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001079#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001080__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001081#endif
1082
Howard Hinnantc834c512011-11-29 18:15:50 +00001083template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001084class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001085{
Howard Hinnantc834c512011-11-29 18:15:50 +00001086 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001087
Howard Hinnantc834c512011-11-29 18:15:50 +00001088 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001089
1090 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001091 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001092
Howard Hinnant74279a52010-09-04 23:28:19 +00001093#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001094 template <class _R1, class _Fp>
1095 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1096 template <class _R1, class _Fp>
1097 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001098#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001099 template <class _R1, class _Fp>
1100 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1101 template <class _R1, class _Fp>
1102 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001103#endif
1104
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001105public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001106 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001107 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001108#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001109 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001110 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001111 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1112 future(const future&) = delete;
1113 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001114 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001115 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001116 {
1117 future(std::move(__rhs)).swap(*this);
1118 return *this;
1119 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001120#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001121private:
1122 future(const future&);
1123 future& operator=(const future&);
1124public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001125#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001126 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001127 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001128 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001129
1130 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001131 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001132
Howard Hinnant684902d2010-09-22 14:16:26 +00001133 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001134 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001135
1136 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001137 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001138 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001139
Howard Hinnant684902d2010-09-22 14:16:26 +00001140 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001141 void wait() const {__state_->wait();}
1142 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001143 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001144 future_status
1145 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1146 {return __state_->wait_for(__rel_time);}
1147 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001148 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001149 future_status
1150 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1151 {return __state_->wait_until(__abs_time);}
1152};
1153
Howard Hinnantc834c512011-11-29 18:15:50 +00001154template <class _Rp>
1155future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001156 : __state_(__state)
1157{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001158 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001159}
1160
Howard Hinnantccdd2032010-08-30 18:46:21 +00001161struct __release_shared_count
1162{
1163 void operator()(__shared_count* p) {p->__release_shared();}
1164};
1165
Howard Hinnantc834c512011-11-29 18:15:50 +00001166template <class _Rp>
1167future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001168{
1169 if (__state_)
1170 __state_->__release_shared();
1171}
1172
Howard Hinnantc834c512011-11-29 18:15:50 +00001173template <class _Rp>
1174_Rp
1175future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001176{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001177 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001178 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001179 __state_ = nullptr;
1180 return __s->move();
1181}
1182
Howard Hinnantc834c512011-11-29 18:15:50 +00001183template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001184class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001185{
Howard Hinnantc834c512011-11-29 18:15:50 +00001186 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001187
Howard Hinnantc834c512011-11-29 18:15:50 +00001188 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001189
1190 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001191 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001192
Howard Hinnant74279a52010-09-04 23:28:19 +00001193#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001194 template <class _R1, class _Fp>
1195 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1196 template <class _R1, class _Fp>
1197 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001198#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001199 template <class _R1, class _Fp>
1200 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1201 template <class _R1, class _Fp>
1202 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001203#endif
1204
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001205public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001206 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001207 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001208#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001209 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001210 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001211 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1212 future(const future&) = delete;
1213 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001214 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001215 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001216 {
1217 future(std::move(__rhs)).swap(*this);
1218 return *this;
1219 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001220#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001221private:
1222 future(const future&);
1223 future& operator=(const future&);
1224public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001225#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001226 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001227 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001228 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001229
1230 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001231 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001232
Howard Hinnant684902d2010-09-22 14:16:26 +00001233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001234 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001235
1236 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001238 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001239
Howard Hinnant684902d2010-09-22 14:16:26 +00001240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001241 void wait() const {__state_->wait();}
1242 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001243 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001244 future_status
1245 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1246 {return __state_->wait_for(__rel_time);}
1247 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001249 future_status
1250 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1251 {return __state_->wait_until(__abs_time);}
1252};
1253
Howard Hinnantc834c512011-11-29 18:15:50 +00001254template <class _Rp>
1255future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001256 : __state_(__state)
1257{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001258 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001259}
1260
Howard Hinnantc834c512011-11-29 18:15:50 +00001261template <class _Rp>
1262future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001263{
1264 if (__state_)
1265 __state_->__release_shared();
1266}
1267
Howard Hinnantc834c512011-11-29 18:15:50 +00001268template <class _Rp>
1269_Rp&
1270future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001271{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001272 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001273 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001274 __state_ = nullptr;
1275 return __s->copy();
1276}
1277
1278template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001279class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001280{
1281 __assoc_sub_state* __state_;
1282
1283 explicit future(__assoc_sub_state* __state);
1284
1285 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001286 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001287
Howard Hinnant74279a52010-09-04 23:28:19 +00001288#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001289 template <class _R1, class _Fp>
1290 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1291 template <class _R1, class _Fp>
1292 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001293#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001294 template <class _R1, class _Fp>
1295 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1296 template <class _R1, class _Fp>
1297 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001298#endif
1299
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001300public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001302 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001303#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001305 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001306 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1307 future(const future&) = delete;
1308 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001310 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001311 {
1312 future(std::move(__rhs)).swap(*this);
1313 return *this;
1314 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001315#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001316private:
1317 future(const future&);
1318 future& operator=(const future&);
1319public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001320#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001321 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001322 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001323 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001324
1325 // retrieving the value
1326 void get();
1327
Howard Hinnant684902d2010-09-22 14:16:26 +00001328 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001329 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001330
1331 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001333 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001334
Howard Hinnant684902d2010-09-22 14:16:26 +00001335 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001336 void wait() const {__state_->wait();}
1337 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001338 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001339 future_status
1340 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1341 {return __state_->wait_for(__rel_time);}
1342 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001344 future_status
1345 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1346 {return __state_->wait_until(__abs_time);}
1347};
1348
Howard Hinnantc834c512011-11-29 18:15:50 +00001349template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001350inline _LIBCPP_INLINE_VISIBILITY
1351void
Howard Hinnant22448042012-07-21 17:46:55 +00001352swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001353{
1354 __x.swap(__y);
1355}
1356
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001357// promise<R>
1358
Howard Hinnant944510a2011-06-14 19:58:17 +00001359template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001360
Howard Hinnantc834c512011-11-29 18:15:50 +00001361template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001362class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001363{
Howard Hinnantc834c512011-11-29 18:15:50 +00001364 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001365
Howard Hinnant684902d2010-09-22 14:16:26 +00001366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001367 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001368
1369 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001370public:
1371 promise();
1372 template <class _Alloc>
1373 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001374#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001376 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001377 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1378 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001379#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001380private:
1381 promise(const promise& __rhs);
1382public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001383#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001384 ~promise();
1385
1386 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001389 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001390 {
1391 promise(std::move(__rhs)).swap(*this);
1392 return *this;
1393 }
1394 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001395#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001396private:
1397 promise& operator=(const promise& __rhs);
1398public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001399#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001401 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001402
1403 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001404 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001405
1406 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001407 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001408#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001409 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001410#endif
1411 void set_exception(exception_ptr __p);
1412
1413 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001414 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001415#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001416 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001417#endif
1418 void set_exception_at_thread_exit(exception_ptr __p);
1419};
1420
Howard Hinnantc834c512011-11-29 18:15:50 +00001421template <class _Rp>
1422promise<_Rp>::promise()
1423 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001424{
1425}
1426
Howard Hinnantc834c512011-11-29 18:15:50 +00001427template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001428template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001429promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001430{
Eric Fiselier0d109272014-10-23 06:24:45 +00001431 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1432 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001433 typedef __allocator_destructor<_A2> _D2;
1434 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001435 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1436 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1437 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001438}
1439
Howard Hinnantc834c512011-11-29 18:15:50 +00001440template <class _Rp>
1441promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001442{
1443 if (__state_)
1444 {
1445 if (!__state_->__has_value() && __state_->use_count() > 1)
1446 __state_->set_exception(make_exception_ptr(
1447 future_error(make_error_code(future_errc::broken_promise))
1448 ));
1449 __state_->__release_shared();
1450 }
1451}
1452
Howard Hinnantc834c512011-11-29 18:15:50 +00001453template <class _Rp>
1454future<_Rp>
1455promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001456{
1457 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001458 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001459 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001460}
1461
Howard Hinnantc834c512011-11-29 18:15:50 +00001462template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001463void
Howard Hinnantc834c512011-11-29 18:15:50 +00001464promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001465{
1466 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001467 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001468 __state_->set_value(__r);
1469}
1470
Howard Hinnant74279a52010-09-04 23:28:19 +00001471#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001472
Howard Hinnantc834c512011-11-29 18:15:50 +00001473template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001474void
Howard Hinnantc834c512011-11-29 18:15:50 +00001475promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001476{
1477 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001478 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001479 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001480}
1481
Howard Hinnant74279a52010-09-04 23:28:19 +00001482#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001483
Howard Hinnantc834c512011-11-29 18:15:50 +00001484template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001485void
Howard Hinnantc834c512011-11-29 18:15:50 +00001486promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001487{
Marshall Clow2b36f572016-05-16 16:55:32 +00001488 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001489 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001490 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001491 __state_->set_exception(__p);
1492}
1493
Howard Hinnantc834c512011-11-29 18:15:50 +00001494template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001495void
Howard Hinnantc834c512011-11-29 18:15:50 +00001496promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001497{
1498 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001499 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001500 __state_->set_value_at_thread_exit(__r);
1501}
1502
Howard Hinnant74279a52010-09-04 23:28:19 +00001503#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504
Howard Hinnantc834c512011-11-29 18:15:50 +00001505template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001506void
Howard Hinnantc834c512011-11-29 18:15:50 +00001507promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001508{
1509 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001510 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001511 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001512}
1513
Howard Hinnant74279a52010-09-04 23:28:19 +00001514#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001515
Howard Hinnantc834c512011-11-29 18:15:50 +00001516template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001517void
Howard Hinnantc834c512011-11-29 18:15:50 +00001518promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001519{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001520 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001521 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001522 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001523 __state_->set_exception_at_thread_exit(__p);
1524}
1525
1526// promise<R&>
1527
Howard Hinnantc834c512011-11-29 18:15:50 +00001528template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001529class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001530{
Howard Hinnantc834c512011-11-29 18:15:50 +00001531 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001532
Howard Hinnant684902d2010-09-22 14:16:26 +00001533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001534 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001535
1536 template <class> friend class packaged_task;
1537
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001538public:
1539 promise();
1540 template <class _Allocator>
1541 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001542#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001543 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001544 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001545 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1546 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001547#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001548private:
1549 promise(const promise& __rhs);
1550public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001551#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001552 ~promise();
1553
1554 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001555#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001557 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001558 {
1559 promise(std::move(__rhs)).swap(*this);
1560 return *this;
1561 }
1562 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001563#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001564private:
1565 promise& operator=(const promise& __rhs);
1566public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001567#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001569 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001570
1571 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001572 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001573
1574 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001575 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001576 void set_exception(exception_ptr __p);
1577
1578 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001579 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001580 void set_exception_at_thread_exit(exception_ptr __p);
1581};
1582
Howard Hinnantc834c512011-11-29 18:15:50 +00001583template <class _Rp>
1584promise<_Rp&>::promise()
1585 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001586{
1587}
1588
Howard Hinnantc834c512011-11-29 18:15:50 +00001589template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001590template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001591promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001592{
Eric Fiselier0d109272014-10-23 06:24:45 +00001593 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1594 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001595 typedef __allocator_destructor<_A2> _D2;
1596 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001597 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1598 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1599 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001600}
1601
Howard Hinnantc834c512011-11-29 18:15:50 +00001602template <class _Rp>
1603promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001604{
1605 if (__state_)
1606 {
1607 if (!__state_->__has_value() && __state_->use_count() > 1)
1608 __state_->set_exception(make_exception_ptr(
1609 future_error(make_error_code(future_errc::broken_promise))
1610 ));
1611 __state_->__release_shared();
1612 }
1613}
1614
Howard Hinnantc834c512011-11-29 18:15:50 +00001615template <class _Rp>
1616future<_Rp&>
1617promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001618{
1619 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001620 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001621 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001622}
1623
Howard Hinnantc834c512011-11-29 18:15:50 +00001624template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001625void
Howard Hinnantc834c512011-11-29 18:15:50 +00001626promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001627{
1628 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001629 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001630 __state_->set_value(__r);
1631}
1632
Howard Hinnantc834c512011-11-29 18:15:50 +00001633template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001634void
Howard Hinnantc834c512011-11-29 18:15:50 +00001635promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001636{
Marshall Clow2b36f572016-05-16 16:55:32 +00001637 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001638 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001639 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001640 __state_->set_exception(__p);
1641}
1642
Howard Hinnantc834c512011-11-29 18:15:50 +00001643template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001644void
Howard Hinnantc834c512011-11-29 18:15:50 +00001645promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001646{
1647 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001648 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001649 __state_->set_value_at_thread_exit(__r);
1650}
1651
Howard Hinnantc834c512011-11-29 18:15:50 +00001652template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001653void
Howard Hinnantc834c512011-11-29 18:15:50 +00001654promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001655{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001656 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001657 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001658 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001659 __state_->set_exception_at_thread_exit(__p);
1660}
1661
1662// promise<void>
1663
1664template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001665class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001666{
1667 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001668
Howard Hinnant684902d2010-09-22 14:16:26 +00001669 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001670 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001671
1672 template <class> friend class packaged_task;
1673
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001674public:
1675 promise();
1676 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001677 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001678 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001679#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001680 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001681 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001682 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1683 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001684#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001685private:
1686 promise(const promise& __rhs);
1687public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001688#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001689 ~promise();
1690
1691 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001692#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001693 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001694 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001695 {
1696 promise(std::move(__rhs)).swap(*this);
1697 return *this;
1698 }
1699 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001700#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001701private:
1702 promise& operator=(const promise& __rhs);
1703public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001704#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001705 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001706 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001707
1708 // retrieving the result
1709 future<void> get_future();
1710
1711 // setting the result
1712 void set_value();
1713 void set_exception(exception_ptr __p);
1714
1715 // setting the result with deferred notification
1716 void set_value_at_thread_exit();
1717 void set_exception_at_thread_exit(exception_ptr __p);
1718};
1719
1720template <class _Alloc>
1721promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1722{
Eric Fiselier0d109272014-10-23 06:24:45 +00001723 typedef __assoc_sub_state_alloc<_Alloc> _State;
1724 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001725 typedef __allocator_destructor<_A2> _D2;
1726 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001727 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1728 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1729 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001730}
1731
Howard Hinnantc834c512011-11-29 18:15:50 +00001732template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001733inline _LIBCPP_INLINE_VISIBILITY
1734void
Howard Hinnant22448042012-07-21 17:46:55 +00001735swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001736{
1737 __x.swap(__y);
1738}
1739
Howard Hinnantc834c512011-11-29 18:15:50 +00001740template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001741 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001742 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001743
Howard Hinnantccdd2032010-08-30 18:46:21 +00001744#ifndef _LIBCPP_HAS_NO_VARIADICS
1745
1746// packaged_task
1747
1748template<class _Fp> class __packaged_task_base;
1749
Howard Hinnantc834c512011-11-29 18:15:50 +00001750template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001751class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001752{
1753 __packaged_task_base(const __packaged_task_base&);
1754 __packaged_task_base& operator=(const __packaged_task_base&);
1755public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001757 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001759 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001760 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001761 virtual void destroy() = 0;
1762 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001763 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001764};
1765
1766template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1767
Howard Hinnantc834c512011-11-29 18:15:50 +00001768template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001769class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001770 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001771{
Howard Hinnantc834c512011-11-29 18:15:50 +00001772 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001773public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001775 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001777 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001779 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001780 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001781 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001782 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001783 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001784 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001785 virtual void destroy();
1786 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001787 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001788};
1789
Howard Hinnantc834c512011-11-29 18:15:50 +00001790template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001791void
Howard Hinnantc834c512011-11-29 18:15:50 +00001792__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001793 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001794{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001795 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001796}
1797
Howard Hinnantc834c512011-11-29 18:15:50 +00001798template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001799void
Howard Hinnantc834c512011-11-29 18:15:50 +00001800__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001801{
Howard Hinnantc834c512011-11-29 18:15:50 +00001802 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001803}
1804
Howard Hinnantc834c512011-11-29 18:15:50 +00001805template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001806void
Howard Hinnantc834c512011-11-29 18:15:50 +00001807__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001808{
Eric Fiselier0d109272014-10-23 06:24:45 +00001809 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1810 typedef allocator_traits<_Ap> _ATraits;
1811 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001812 _Ap __a(__f_.second());
1813 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001814 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001815}
1816
Howard Hinnantc834c512011-11-29 18:15:50 +00001817template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1818_Rp
1819__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001820{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001821 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001822}
1823
Howard Hinnant944510a2011-06-14 19:58:17 +00001824template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001825
Howard Hinnantc834c512011-11-29 18:15:50 +00001826template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001827class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001828{
Howard Hinnantc834c512011-11-29 18:15:50 +00001829 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
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;
1863 else if (__f.__f_ == (__base*)&__f.__buf_)
1864 {
1865 __f_ = (__base*)&__buf_;
1866 __f.__f_->__move_to(__f_);
1867 }
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 {
1884 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001885 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
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{
1927 if (__f_ == (__base*)&__buf_)
1928 __f_->destroy();
1929 else if (__f_)
1930 __f_->destroy_deallocate();
1931 __f_ = nullptr;
1932 if (__f.__f_ == nullptr)
1933 __f_ = nullptr;
1934 else if (__f.__f_ == (__base*)&__f.__buf_)
1935 {
1936 __f_ = (__base*)&__buf_;
1937 __f.__f_->__move_to(__f_);
1938 }
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{
1950 if (__f_ == (__base*)&__buf_)
1951 __f_->destroy();
1952 else if (__f_)
1953 __f_->destroy_deallocate();
1954}
1955
Howard Hinnantc834c512011-11-29 18:15:50 +00001956template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001957void
Howard Hinnant22448042012-07-21 17:46:55 +00001958__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001959{
1960 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1961 {
1962 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1963 __base* __t = (__base*)&__tempbuf;
1964 __f_->__move_to(__t);
1965 __f_->destroy();
1966 __f_ = nullptr;
1967 __f.__f_->__move_to((__base*)&__buf_);
1968 __f.__f_->destroy();
1969 __f.__f_ = nullptr;
1970 __f_ = (__base*)&__buf_;
1971 __t->__move_to((__base*)&__f.__buf_);
1972 __t->destroy();
1973 __f.__f_ = (__base*)&__f.__buf_;
1974 }
1975 else if (__f_ == (__base*)&__buf_)
1976 {
1977 __f_->__move_to((__base*)&__f.__buf_);
1978 __f_->destroy();
1979 __f_ = __f.__f_;
1980 __f.__f_ = (__base*)&__f.__buf_;
1981 }
1982 else if (__f.__f_ == (__base*)&__f.__buf_)
1983 {
1984 __f.__f_->__move_to((__base*)&__buf_);
1985 __f.__f_->destroy();
1986 __f.__f_ = __f_;
1987 __f_ = (__base*)&__buf_;
1988 }
1989 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001990 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001991}
1992
Howard Hinnantc834c512011-11-29 18:15:50 +00001993template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001994inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001995_Rp
1996__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001997{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001998 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001999}
2000
Howard Hinnantc834c512011-11-29 18:15:50 +00002001template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002002class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002003{
2004public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002005 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002006
2007private:
2008 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2009 promise<result_type> __p_;
2010
2011public:
2012 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002013 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002014 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002015 template <class _Fp,
2016 class = typename enable_if
2017 <
2018 !is_same<
Marshall Clowaaf031b2018-03-20 22:37:37 +00002019 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002020 packaged_task
2021 >::value
2022 >::type
2023 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002024 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002025 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002026 template <class _Fp, class _Allocator,
2027 class = typename enable_if
2028 <
2029 !is_same<
Marshall Clowaaf031b2018-03-20 22:37:37 +00002030 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002031 packaged_task
2032 >::value
2033 >::type
2034 >
2035 _LIBCPP_INLINE_VISIBILITY
2036 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2037 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2038 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002039 // ~packaged_task() = default;
2040
2041 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002042 packaged_task(const packaged_task&) = delete;
2043 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002044
2045 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002046 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002047 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002048 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002049 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002050 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002051 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002052 __f_ = _VSTD::move(__other.__f_);
2053 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002054 return *this;
2055 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002057 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002058 {
2059 __f_.swap(__other.__f_);
2060 __p_.swap(__other.__p_);
2061 }
2062
Howard Hinnant684902d2010-09-22 14:16:26 +00002063 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002064 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002065
2066 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002067 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002068 future<result_type> get_future() {return __p_.get_future();}
2069
2070 // execution
2071 void operator()(_ArgTypes... __args);
2072 void make_ready_at_thread_exit(_ArgTypes... __args);
2073
2074 void reset();
2075};
2076
Howard Hinnantc834c512011-11-29 18:15:50 +00002077template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002078void
Howard Hinnantc834c512011-11-29 18:15:50 +00002079packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002080{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002082 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002083 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002084 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002085#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002086 try
2087 {
2088#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002089 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002090#ifndef _LIBCPP_NO_EXCEPTIONS
2091 }
2092 catch (...)
2093 {
2094 __p_.set_exception(current_exception());
2095 }
2096#endif // _LIBCPP_NO_EXCEPTIONS
2097}
2098
Howard Hinnantc834c512011-11-29 18:15:50 +00002099template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002100void
Howard Hinnantc834c512011-11-29 18:15:50 +00002101packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002102{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002103 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002104 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002105 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002106 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002107#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002108 try
2109 {
2110#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002111 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002112#ifndef _LIBCPP_NO_EXCEPTIONS
2113 }
2114 catch (...)
2115 {
2116 __p_.set_exception_at_thread_exit(current_exception());
2117 }
2118#endif // _LIBCPP_NO_EXCEPTIONS
2119}
2120
Howard Hinnantc834c512011-11-29 18:15:50 +00002121template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002122void
Howard Hinnantc834c512011-11-29 18:15:50 +00002123packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002124{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002125 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002126 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002127 __p_ = promise<result_type>();
2128}
2129
2130template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002131class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002132{
2133public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002134 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002135
2136private:
2137 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2138 promise<result_type> __p_;
2139
2140public:
2141 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002142 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002143 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002144 template <class _Fp,
2145 class = typename enable_if
2146 <
2147 !is_same<
Marshall Clowaaf031b2018-03-20 22:37:37 +00002148 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002149 packaged_task
2150 >::value
2151 >::type
2152 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002153 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002154 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002155 template <class _Fp, class _Allocator,
2156 class = typename enable_if
2157 <
2158 !is_same<
Marshall Clowaaf031b2018-03-20 22:37:37 +00002159 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002160 packaged_task
2161 >::value
2162 >::type
2163 >
2164 _LIBCPP_INLINE_VISIBILITY
2165 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2166 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2167 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002168 // ~packaged_task() = default;
2169
2170 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002171 packaged_task(const packaged_task&) = delete;
2172 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002173
2174 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002176 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002177 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002178 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002179 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002180 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002181 __f_ = _VSTD::move(__other.__f_);
2182 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002183 return *this;
2184 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002185 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002186 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002187 {
2188 __f_.swap(__other.__f_);
2189 __p_.swap(__other.__p_);
2190 }
2191
Howard Hinnant684902d2010-09-22 14:16:26 +00002192 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002193 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002194
2195 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002196 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002197 future<result_type> get_future() {return __p_.get_future();}
2198
2199 // execution
2200 void operator()(_ArgTypes... __args);
2201 void make_ready_at_thread_exit(_ArgTypes... __args);
2202
2203 void reset();
2204};
2205
2206template<class ..._ArgTypes>
2207void
2208packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2209{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002210 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002211 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002212 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002213 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002214#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002215 try
2216 {
2217#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002218 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002219 __p_.set_value();
2220#ifndef _LIBCPP_NO_EXCEPTIONS
2221 }
2222 catch (...)
2223 {
2224 __p_.set_exception(current_exception());
2225 }
2226#endif // _LIBCPP_NO_EXCEPTIONS
2227}
2228
2229template<class ..._ArgTypes>
2230void
2231packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2232{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002233 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002234 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002235 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002236 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002237#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002238 try
2239 {
2240#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002241 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002242 __p_.set_value_at_thread_exit();
2243#ifndef _LIBCPP_NO_EXCEPTIONS
2244 }
2245 catch (...)
2246 {
2247 __p_.set_exception_at_thread_exit(current_exception());
2248 }
2249#endif // _LIBCPP_NO_EXCEPTIONS
2250}
2251
2252template<class ..._ArgTypes>
2253void
2254packaged_task<void(_ArgTypes...)>::reset()
2255{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002256 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002257 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002258 __p_ = promise<result_type>();
2259}
2260
2261template <class _Callable>
2262inline _LIBCPP_INLINE_VISIBILITY
2263void
Howard Hinnant22448042012-07-21 17:46:55 +00002264swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002265{
2266 __x.swap(__y);
2267}
2268
Marshall Clowa0a057e2017-11-27 20:47:54 +00002269template <class _Callable, class _Alloc>
2270struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2271 : public true_type {};
2272
Howard Hinnantc834c512011-11-29 18:15:50 +00002273template <class _Rp, class _Fp>
2274future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002275#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002276__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002277#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002278__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002279#endif
2280{
Howard Hinnantc834c512011-11-29 18:15:50 +00002281 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2282 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2283 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002284}
2285
Howard Hinnantc834c512011-11-29 18:15:50 +00002286template <class _Rp, class _Fp>
2287future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002288#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002289__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002290#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002291__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002292#endif
2293{
Howard Hinnantc834c512011-11-29 18:15:50 +00002294 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2295 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2296 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2297 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002298}
2299
Howard Hinnantc834c512011-11-29 18:15:50 +00002300template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002301class __async_func
2302{
Howard Hinnantc834c512011-11-29 18:15:50 +00002303 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002304
2305public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002306 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002307
2308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002309 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002310 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002311
2312 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002313 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002314
Howard Hinnantc834c512011-11-29 18:15:50 +00002315 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002316 {
2317 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2318 return __execute(_Index());
2319 }
2320private:
2321 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002322 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002323 __execute(__tuple_indices<_Indices...>)
2324 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002325 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002326 }
2327};
2328
Marshall Clowd56a5b62013-11-03 22:06:53 +00002329inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002330{ return (int(__policy) & int(__value)) != 0; }
2331
Howard Hinnantc834c512011-11-29 18:15:50 +00002332template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002333_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002334future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2335async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002336{
Howard Hinnantc834c512011-11-29 18:15:50 +00002337 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2338 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002339
2340#ifndef _LIBCPP_NO_EXCEPTIONS
2341 try
2342 {
2343#endif
2344 if (__does_policy_contain(__policy, launch::async))
2345 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002346 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002347#ifndef _LIBCPP_NO_EXCEPTIONS
2348 }
2349 catch ( ... ) { if (__policy == launch::async) throw ; }
2350#endif
2351
2352 if (__does_policy_contain(__policy, launch::deferred))
2353 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002354 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002355 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002356}
2357
Howard Hinnantc834c512011-11-29 18:15:50 +00002358template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002359_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002360future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2361async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002362{
Howard Hinnantc834c512011-11-29 18:15:50 +00002363 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002364 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002365}
2366
2367#endif // _LIBCPP_HAS_NO_VARIADICS
2368
Howard Hinnante6a10852010-09-03 21:46:37 +00002369// shared_future
2370
Howard Hinnantc834c512011-11-29 18:15:50 +00002371template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002372class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002373{
Howard Hinnantc834c512011-11-29 18:15:50 +00002374 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002375
2376public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002377 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002378 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002379 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002380 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002381 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002382#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002384 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002385 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002386 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002387 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002388 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002389#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002390 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002391 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant74279a52010-09-04 23:28:19 +00002392#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002393 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002394 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002395 {
2396 shared_future(std::move(__rhs)).swap(*this);
2397 return *this;
2398 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002399#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002400
2401 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002403 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002404
Howard Hinnant684902d2010-09-22 14:16:26 +00002405 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002406 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002407
2408 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002409 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002410 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002411
Howard Hinnant684902d2010-09-22 14:16:26 +00002412 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002413 void wait() const {__state_->wait();}
2414 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002415 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002416 future_status
2417 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2418 {return __state_->wait_for(__rel_time);}
2419 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002421 future_status
2422 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2423 {return __state_->wait_until(__abs_time);}
2424};
2425
Howard Hinnantc834c512011-11-29 18:15:50 +00002426template <class _Rp>
2427shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002428{
2429 if (__state_)
2430 __state_->__release_shared();
2431}
2432
Howard Hinnantc834c512011-11-29 18:15:50 +00002433template <class _Rp>
2434shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002435shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002436{
2437 if (__rhs.__state_)
2438 __rhs.__state_->__add_shared();
2439 if (__state_)
2440 __state_->__release_shared();
2441 __state_ = __rhs.__state_;
2442 return *this;
2443}
2444
Howard Hinnantc834c512011-11-29 18:15:50 +00002445template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002446class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002447{
Howard Hinnantc834c512011-11-29 18:15:50 +00002448 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002449
2450public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002451 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002452 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002454 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2455 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002456#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002458 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002459 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002460 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002461 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002462 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002463#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002464 ~shared_future();
2465 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002466#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002467 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002468 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002469 {
2470 shared_future(std::move(__rhs)).swap(*this);
2471 return *this;
2472 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002473#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002474
2475 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002477 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002478
Howard Hinnant684902d2010-09-22 14:16:26 +00002479 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002480 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002481
2482 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002484 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002485
Howard Hinnant684902d2010-09-22 14:16:26 +00002486 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002487 void wait() const {__state_->wait();}
2488 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002489 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002490 future_status
2491 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2492 {return __state_->wait_for(__rel_time);}
2493 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002494 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002495 future_status
2496 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2497 {return __state_->wait_until(__abs_time);}
2498};
2499
Howard Hinnantc834c512011-11-29 18:15:50 +00002500template <class _Rp>
2501shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002502{
2503 if (__state_)
2504 __state_->__release_shared();
2505}
2506
Howard Hinnantc834c512011-11-29 18:15:50 +00002507template <class _Rp>
2508shared_future<_Rp&>&
2509shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002510{
2511 if (__rhs.__state_)
2512 __rhs.__state_->__add_shared();
2513 if (__state_)
2514 __state_->__release_shared();
2515 __state_ = __rhs.__state_;
2516 return *this;
2517}
2518
2519template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002520class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002521{
2522 __assoc_sub_state* __state_;
2523
2524public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002525 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002526 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002527 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002528 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2529 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002530#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002531 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002532 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002533 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002535 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002536 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002537#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002538 ~shared_future();
2539 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002540#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002541 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002542 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002543 {
2544 shared_future(std::move(__rhs)).swap(*this);
2545 return *this;
2546 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002547#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002548
2549 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002551 void get() const {__state_->copy();}
2552
Howard Hinnant684902d2010-09-22 14:16:26 +00002553 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002554 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002555
2556 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002557 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002558 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002559
Howard Hinnant684902d2010-09-22 14:16:26 +00002560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002561 void wait() const {__state_->wait();}
2562 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002564 future_status
2565 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2566 {return __state_->wait_for(__rel_time);}
2567 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002569 future_status
2570 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2571 {return __state_->wait_until(__abs_time);}
2572};
2573
Howard Hinnantc834c512011-11-29 18:15:50 +00002574template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002575inline _LIBCPP_INLINE_VISIBILITY
2576void
Howard Hinnant22448042012-07-21 17:46:55 +00002577swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002578{
2579 __x.swap(__y);
2580}
2581
Howard Hinnantc834c512011-11-29 18:15:50 +00002582template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002583inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002584shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002585future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002586{
Howard Hinnantc834c512011-11-29 18:15:50 +00002587 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002588}
2589
Howard Hinnantc834c512011-11-29 18:15:50 +00002590template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002591inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002592shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002593future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002594{
Howard Hinnantc834c512011-11-29 18:15:50 +00002595 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002596}
2597
Howard Hinnante65e8e32010-12-02 16:45:21 +00002598#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2599
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002600inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002601shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002602future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002603{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002604 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002605}
2606
Howard Hinnante65e8e32010-12-02 16:45:21 +00002607#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2608
Howard Hinnantc51e1022010-05-11 19:42:16 +00002609_LIBCPP_END_NAMESPACE_STD
2610
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002611#endif // !_LIBCPP_HAS_NO_THREADS
2612
Howard Hinnantc51e1022010-05-11 19:42:16 +00002613#endif // _LIBCPP_FUTURE