blob: 1ceedf91e9cdc1f3a835ef4df8441fb6d036cc13 [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);
331 template <class F, class Allocator>
Marshall Clowc317e022015-06-30 14:16:49 +0000332 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
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // 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
412#ifdef _LIBCXX_UNDERLYING_TYPE
413typedef 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
Howard Hinnant684902d2010-09-22 14:16:26 +0000502class _LIBCPP_EXCEPTION_ABI 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
Marshall Clow8fea1612016-08-25 15:09:01 +0000517_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
Eric Fiselier43641592015-10-02 21:25:15 +0000518void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000519{
520#ifndef _LIBCPP_NO_EXCEPTIONS
521 throw future_error(make_error_code(_Ev));
522#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000523 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000524 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000525#endif
526}
527
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000528class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000529 : public __shared_count
530{
531protected:
532 exception_ptr __exception_;
533 mutable mutex __mut_;
534 mutable condition_variable __cv_;
535 unsigned __state_;
536
Howard Hinnant719bda32011-05-28 14:41:13 +0000537 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000538 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000539public:
540 enum
541 {
542 __constructed = 1,
543 __future_attached = 2,
544 ready = 4,
545 deferred = 8
546 };
547
Howard Hinnant684902d2010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000549 __assoc_sub_state() : __state_(0) {}
550
Howard Hinnant684902d2010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000552 bool __has_value() const
553 {return (__state_ & __constructed) || (__exception_ != nullptr);}
554
Howard Hinnant684902d2010-09-22 14:16:26 +0000555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante667ecc2013-01-14 20:01:24 +0000556 void __set_future_attached()
557 {
558 lock_guard<mutex> __lk(__mut_);
559 __state_ |= __future_attached;
560 }
Howard Hinnant684902d2010-09-22 14:16:26 +0000561 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000562 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000563
Howard Hinnant684902d2010-09-22 14:16:26 +0000564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000565 void __set_deferred() {__state_ |= deferred;}
566
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000568 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000569 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000570
571 void set_value();
572 void set_value_at_thread_exit();
573
574 void set_exception(exception_ptr __p);
575 void set_exception_at_thread_exit(exception_ptr __p);
576
577 void copy();
578
Howard Hinnantccdd2032010-08-30 18:46:21 +0000579 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000580 template <class _Rep, class _Period>
581 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000583 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
584 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000585 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000586 future_status
587 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000588
589 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000590};
591
Howard Hinnantf4712b92010-08-28 21:01:06 +0000592template <class _Clock, class _Duration>
593future_status
594__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
595{
596 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000597 if (__state_ & deferred)
598 return future_status::deferred;
599 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000600 __cv_.wait_until(__lk, __abs_time);
601 if (__state_ & ready)
602 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000603 return future_status::timeout;
604}
605
606template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000607inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000608future_status
609__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
610{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000611 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000612}
613
Howard Hinnantc834c512011-11-29 18:15:50 +0000614template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000615class __assoc_state
616 : public __assoc_sub_state
617{
618 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000619 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000621 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000622
Howard Hinnant719bda32011-05-28 14:41:13 +0000623 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000624public:
625
626 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000627#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000628 void set_value(_Arg&& __arg);
629#else
630 void set_value(_Arg& __arg);
631#endif
632
633 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000634#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000635 void set_value_at_thread_exit(_Arg&& __arg);
636#else
637 void set_value_at_thread_exit(_Arg& __arg);
638#endif
639
Howard Hinnantc834c512011-11-29 18:15:50 +0000640 _Rp move();
641 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000642};
643
Howard Hinnantc834c512011-11-29 18:15:50 +0000644template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000645void
Howard Hinnantc834c512011-11-29 18:15:50 +0000646__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000647{
648 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000649 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000650 delete this;
651}
652
Howard Hinnantc834c512011-11-29 18:15:50 +0000653template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000654template <class _Arg>
655void
Howard Hinnant74279a52010-09-04 23:28:19 +0000656#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000657__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000658#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000659__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000660#endif
661{
662 unique_lock<mutex> __lk(this->__mut_);
663 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000664 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000665 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000666 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000667 __cv_.notify_all();
668}
669
Howard Hinnantc834c512011-11-29 18:15:50 +0000670template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000671template <class _Arg>
672void
Howard Hinnant74279a52010-09-04 23:28:19 +0000673#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000674__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000676__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000677#endif
678{
679 unique_lock<mutex> __lk(this->__mut_);
680 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000681 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000682 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000683 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000684 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000685}
686
Howard Hinnantc834c512011-11-29 18:15:50 +0000687template <class _Rp>
688_Rp
689__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000690{
691 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000692 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000693 if (this->__exception_ != nullptr)
694 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000695 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000696}
697
Howard Hinnantc834c512011-11-29 18:15:50 +0000698template <class _Rp>
699typename add_lvalue_reference<_Rp>::type
700__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000701{
702 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000703 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000704 if (this->__exception_ != nullptr)
705 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000706 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000707}
708
Howard Hinnantc834c512011-11-29 18:15:50 +0000709template <class _Rp>
710class __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000711 : public __assoc_sub_state
712{
713 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000714 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000716 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000717
Howard Hinnant719bda32011-05-28 14:41:13 +0000718 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000719public:
720
Howard Hinnantc834c512011-11-29 18:15:50 +0000721 void set_value(_Rp& __arg);
722 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000723
Howard Hinnantc834c512011-11-29 18:15:50 +0000724 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000725};
726
Howard Hinnantc834c512011-11-29 18:15:50 +0000727template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728void
Howard Hinnantc834c512011-11-29 18:15:50 +0000729__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000730{
731 delete this;
732}
733
Howard Hinnantc834c512011-11-29 18:15:50 +0000734template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000735void
Howard Hinnantc834c512011-11-29 18:15:50 +0000736__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000737{
738 unique_lock<mutex> __lk(this->__mut_);
739 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000740 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000741 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000742 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743 __cv_.notify_all();
744}
745
Howard Hinnantc834c512011-11-29 18:15:50 +0000746template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000747void
Howard Hinnantc834c512011-11-29 18:15:50 +0000748__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000749{
750 unique_lock<mutex> __lk(this->__mut_);
751 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000752 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000753 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000754 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000755 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000756}
757
Howard Hinnantc834c512011-11-29 18:15:50 +0000758template <class _Rp>
759_Rp&
760__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000761{
762 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000763 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000764 if (this->__exception_ != nullptr)
765 rethrow_exception(this->__exception_);
766 return *__value_;
767}
768
Howard Hinnantc834c512011-11-29 18:15:50 +0000769template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000770class __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000771 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000772{
Howard Hinnantc834c512011-11-29 18:15:50 +0000773 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000774 _Alloc __alloc_;
775
Howard Hinnant719bda32011-05-28 14:41:13 +0000776 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000777public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000779 explicit __assoc_state_alloc(const _Alloc& __a)
780 : __alloc_(__a) {}
781};
782
Howard Hinnantc834c512011-11-29 18:15:50 +0000783template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000784void
Howard Hinnantc834c512011-11-29 18:15:50 +0000785__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000786{
787 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000788 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000789 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
790 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000791 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000792 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000793 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000794 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000795}
796
Howard Hinnantc834c512011-11-29 18:15:50 +0000797template <class _Rp, class _Alloc>
798class __assoc_state_alloc<_Rp&, _Alloc>
799 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000800{
Howard Hinnantc834c512011-11-29 18:15:50 +0000801 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000802 _Alloc __alloc_;
803
Howard Hinnant719bda32011-05-28 14:41:13 +0000804 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000805public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000806 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000807 explicit __assoc_state_alloc(const _Alloc& __a)
808 : __alloc_(__a) {}
809};
810
Howard Hinnantc834c512011-11-29 18:15:50 +0000811template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000812void
Howard Hinnantc834c512011-11-29 18:15:50 +0000813__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000814{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000815 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
816 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000817 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000818 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000819 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000820 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000821}
822
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000823template <class _Alloc>
824class __assoc_sub_state_alloc
825 : public __assoc_sub_state
826{
827 typedef __assoc_sub_state base;
828 _Alloc __alloc_;
829
Howard Hinnant719bda32011-05-28 14:41:13 +0000830 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000831public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000832 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000833 explicit __assoc_sub_state_alloc(const _Alloc& __a)
834 : __alloc_(__a) {}
835};
836
837template <class _Alloc>
838void
Howard Hinnant719bda32011-05-28 14:41:13 +0000839__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000840{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000841 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
842 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000843 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000844 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000845 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000846 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000847}
848
Howard Hinnantc834c512011-11-29 18:15:50 +0000849template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000850class __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000851 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000852{
Howard Hinnantc834c512011-11-29 18:15:50 +0000853 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000854
Howard Hinnantc834c512011-11-29 18:15:50 +0000855 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000856
857public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000858#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000859 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000860 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000861#endif
862
863 virtual void __execute();
864};
865
Howard Hinnant74279a52010-09-04 23:28:19 +0000866#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000867
Howard Hinnantc834c512011-11-29 18:15:50 +0000868template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000869inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000870__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
871 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000872{
873 this->__set_deferred();
874}
875
Howard Hinnant74279a52010-09-04 23:28:19 +0000876#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000877
Howard Hinnantc834c512011-11-29 18:15:50 +0000878template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000879void
Howard Hinnantc834c512011-11-29 18:15:50 +0000880__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000881{
882#ifndef _LIBCPP_NO_EXCEPTIONS
883 try
884 {
885#endif // _LIBCPP_NO_EXCEPTIONS
886 this->set_value(__func_());
887#ifndef _LIBCPP_NO_EXCEPTIONS
888 }
889 catch (...)
890 {
891 this->set_exception(current_exception());
892 }
893#endif // _LIBCPP_NO_EXCEPTIONS
894}
895
Howard Hinnantc834c512011-11-29 18:15:50 +0000896template <class _Fp>
897class __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000898 : public __assoc_sub_state
899{
900 typedef __assoc_sub_state base;
901
Howard Hinnantc834c512011-11-29 18:15:50 +0000902 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000903
904public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000905#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000906 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000907 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000908#endif
909
910 virtual void __execute();
911};
912
Howard Hinnant74279a52010-09-04 23:28:19 +0000913#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000914
Howard Hinnantc834c512011-11-29 18:15:50 +0000915template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000916inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000917__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
918 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000919{
920 this->__set_deferred();
921}
922
Howard Hinnant74279a52010-09-04 23:28:19 +0000923#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000924
Howard Hinnantc834c512011-11-29 18:15:50 +0000925template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000926void
Howard Hinnantc834c512011-11-29 18:15:50 +0000927__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000928{
929#ifndef _LIBCPP_NO_EXCEPTIONS
930 try
931 {
932#endif // _LIBCPP_NO_EXCEPTIONS
933 __func_();
934 this->set_value();
935#ifndef _LIBCPP_NO_EXCEPTIONS
936 }
937 catch (...)
938 {
939 this->set_exception(current_exception());
940 }
941#endif // _LIBCPP_NO_EXCEPTIONS
942}
943
Howard Hinnantc834c512011-11-29 18:15:50 +0000944template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000945class __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000946 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000947{
Howard Hinnantc834c512011-11-29 18:15:50 +0000948 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000949
Howard Hinnantc834c512011-11-29 18:15:50 +0000950 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000951
Howard Hinnant719bda32011-05-28 14:41:13 +0000952 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000953public:
954#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000955 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000956 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000957#endif
958
959 virtual void __execute();
960};
961
962#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
963
Howard Hinnantc834c512011-11-29 18:15:50 +0000964template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000965inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000966__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
967 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000968{
969}
970
971#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
972
Howard Hinnantc834c512011-11-29 18:15:50 +0000973template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000974void
Howard Hinnantc834c512011-11-29 18:15:50 +0000975__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000976{
977#ifndef _LIBCPP_NO_EXCEPTIONS
978 try
979 {
980#endif // _LIBCPP_NO_EXCEPTIONS
981 this->set_value(__func_());
982#ifndef _LIBCPP_NO_EXCEPTIONS
983 }
984 catch (...)
985 {
986 this->set_exception(current_exception());
987 }
988#endif // _LIBCPP_NO_EXCEPTIONS
989}
990
Howard Hinnantc834c512011-11-29 18:15:50 +0000991template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000992void
Howard Hinnantc834c512011-11-29 18:15:50 +0000993__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000994{
995 this->wait();
996 base::__on_zero_shared();
997}
998
Howard Hinnantc834c512011-11-29 18:15:50 +0000999template <class _Fp>
1000class __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001001 : public __assoc_sub_state
1002{
1003 typedef __assoc_sub_state base;
1004
Howard Hinnantc834c512011-11-29 18:15:50 +00001005 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001006
Howard Hinnant719bda32011-05-28 14:41:13 +00001007 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001008public:
1009#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001010 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001011 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001012#endif
1013
1014 virtual void __execute();
1015};
1016
1017#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018
Howard Hinnantc834c512011-11-29 18:15:50 +00001019template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001020inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001021__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1022 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001023{
1024}
1025
1026#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1027
Howard Hinnantc834c512011-11-29 18:15:50 +00001028template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001029void
Howard Hinnantc834c512011-11-29 18:15:50 +00001030__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001031{
1032#ifndef _LIBCPP_NO_EXCEPTIONS
1033 try
1034 {
1035#endif // _LIBCPP_NO_EXCEPTIONS
1036 __func_();
1037 this->set_value();
1038#ifndef _LIBCPP_NO_EXCEPTIONS
1039 }
1040 catch (...)
1041 {
1042 this->set_exception(current_exception());
1043 }
1044#endif // _LIBCPP_NO_EXCEPTIONS
1045}
1046
Howard Hinnantc834c512011-11-29 18:15:50 +00001047template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001048void
Howard Hinnantc834c512011-11-29 18:15:50 +00001049__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001050{
1051 this->wait();
1052 base::__on_zero_shared();
1053}
1054
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001055template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1056template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001057
1058// future
1059
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001060template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001061
Howard Hinnantc834c512011-11-29 18:15:50 +00001062template <class _Rp, class _Fp>
1063future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001064#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001065__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001066#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001067__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001068#endif
1069
Howard Hinnantc834c512011-11-29 18:15:50 +00001070template <class _Rp, class _Fp>
1071future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001072#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001073__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001074#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001075__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001076#endif
1077
Howard Hinnantc834c512011-11-29 18:15:50 +00001078template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001079class _LIBCPP_TEMPLATE_VIS future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001080{
Howard Hinnantc834c512011-11-29 18:15:50 +00001081 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001082
Howard Hinnantc834c512011-11-29 18:15:50 +00001083 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001084
1085 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001086 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001087
Howard Hinnant74279a52010-09-04 23:28:19 +00001088#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001089 template <class _R1, class _Fp>
1090 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1091 template <class _R1, class _Fp>
1092 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001093#else
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#endif
1099
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001100public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001101 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001102 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001103#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001104 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001105 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001106 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1107 future(const future&) = delete;
1108 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001109 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001110 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001111 {
1112 future(std::move(__rhs)).swap(*this);
1113 return *this;
1114 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001115#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001116private:
1117 future(const future&);
1118 future& operator=(const future&);
1119public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001120#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001121 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001122 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001123 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001124
1125 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001126 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001127
Howard Hinnant684902d2010-09-22 14:16:26 +00001128 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001129 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001130
1131 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001133 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001134
Howard Hinnant684902d2010-09-22 14:16:26 +00001135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001136 void wait() const {__state_->wait();}
1137 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001138 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001139 future_status
1140 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1141 {return __state_->wait_for(__rel_time);}
1142 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001143 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001144 future_status
1145 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1146 {return __state_->wait_until(__abs_time);}
1147};
1148
Howard Hinnantc834c512011-11-29 18:15:50 +00001149template <class _Rp>
1150future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001151 : __state_(__state)
1152{
1153 if (__state_->__has_future_attached())
Eric Fiselier43641592015-10-02 21:25:15 +00001154 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001155 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001156 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001157}
1158
Howard Hinnantccdd2032010-08-30 18:46:21 +00001159struct __release_shared_count
1160{
1161 void operator()(__shared_count* p) {p->__release_shared();}
1162};
1163
Howard Hinnantc834c512011-11-29 18:15:50 +00001164template <class _Rp>
1165future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001166{
1167 if (__state_)
1168 __state_->__release_shared();
1169}
1170
Howard Hinnantc834c512011-11-29 18:15:50 +00001171template <class _Rp>
1172_Rp
1173future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001174{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001175 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001176 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001177 __state_ = nullptr;
1178 return __s->move();
1179}
1180
Howard Hinnantc834c512011-11-29 18:15:50 +00001181template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001182class _LIBCPP_TEMPLATE_VIS future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001183{
Howard Hinnantc834c512011-11-29 18:15:50 +00001184 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001185
Howard Hinnantc834c512011-11-29 18:15:50 +00001186 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001187
1188 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001189 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001190
Howard Hinnant74279a52010-09-04 23:28:19 +00001191#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001192 template <class _R1, class _Fp>
1193 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1194 template <class _R1, class _Fp>
1195 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001196#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001197 template <class _R1, class _Fp>
1198 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1199 template <class _R1, class _Fp>
1200 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001201#endif
1202
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001203public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001204 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001205 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001206#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001207 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001208 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001209 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1210 future(const future&) = delete;
1211 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001212 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001213 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001214 {
1215 future(std::move(__rhs)).swap(*this);
1216 return *this;
1217 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001218#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001219private:
1220 future(const future&);
1221 future& operator=(const future&);
1222public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001223#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001224 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001225 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001226 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001227
1228 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001229 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001230
Howard Hinnant684902d2010-09-22 14:16:26 +00001231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001232 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001233
1234 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001235 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001236 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001237
Howard Hinnant684902d2010-09-22 14:16:26 +00001238 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001239 void wait() const {__state_->wait();}
1240 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001241 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001242 future_status
1243 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1244 {return __state_->wait_for(__rel_time);}
1245 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001246 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001247 future_status
1248 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1249 {return __state_->wait_until(__abs_time);}
1250};
1251
Howard Hinnantc834c512011-11-29 18:15:50 +00001252template <class _Rp>
1253future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001254 : __state_(__state)
1255{
1256 if (__state_->__has_future_attached())
Eric Fiselier43641592015-10-02 21:25:15 +00001257 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001258 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001259 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001260}
1261
Howard Hinnantc834c512011-11-29 18:15:50 +00001262template <class _Rp>
1263future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001264{
1265 if (__state_)
1266 __state_->__release_shared();
1267}
1268
Howard Hinnantc834c512011-11-29 18:15:50 +00001269template <class _Rp>
1270_Rp&
1271future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001272{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001273 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001274 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001275 __state_ = nullptr;
1276 return __s->copy();
1277}
1278
1279template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001280class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001281{
1282 __assoc_sub_state* __state_;
1283
1284 explicit future(__assoc_sub_state* __state);
1285
1286 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001287 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001288
Howard Hinnant74279a52010-09-04 23:28:19 +00001289#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001290 template <class _R1, class _Fp>
1291 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1292 template <class _R1, class _Fp>
1293 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001294#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001295 template <class _R1, class _Fp>
1296 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1297 template <class _R1, class _Fp>
1298 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001299#endif
1300
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001301public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001302 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001303 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001304#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001306 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001307 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1308 future(const future&) = delete;
1309 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001311 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001312 {
1313 future(std::move(__rhs)).swap(*this);
1314 return *this;
1315 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001316#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001317private:
1318 future(const future&);
1319 future& operator=(const future&);
1320public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001321#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001322 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001323 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001324 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001325
1326 // retrieving the value
1327 void get();
1328
Howard Hinnant684902d2010-09-22 14:16:26 +00001329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001330 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001331
1332 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001334 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001335
Howard Hinnant684902d2010-09-22 14:16:26 +00001336 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001337 void wait() const {__state_->wait();}
1338 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001340 future_status
1341 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1342 {return __state_->wait_for(__rel_time);}
1343 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001344 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001345 future_status
1346 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1347 {return __state_->wait_until(__abs_time);}
1348};
1349
Howard Hinnantc834c512011-11-29 18:15:50 +00001350template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001351inline _LIBCPP_INLINE_VISIBILITY
1352void
Howard Hinnant22448042012-07-21 17:46:55 +00001353swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001354{
1355 __x.swap(__y);
1356}
1357
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001358// promise<R>
1359
Howard Hinnant944510a2011-06-14 19:58:17 +00001360template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001361
Howard Hinnantc834c512011-11-29 18:15:50 +00001362template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001363class _LIBCPP_TEMPLATE_VIS promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001364{
Howard Hinnantc834c512011-11-29 18:15:50 +00001365 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001366
Howard Hinnant684902d2010-09-22 14:16:26 +00001367 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001368 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001369
1370 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001371public:
1372 promise();
1373 template <class _Alloc>
1374 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001375#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001376 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001377 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001378 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1379 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001380#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001381private:
1382 promise(const promise& __rhs);
1383public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001384#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001385 ~promise();
1386
1387 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001388#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001389 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001390 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001391 {
1392 promise(std::move(__rhs)).swap(*this);
1393 return *this;
1394 }
1395 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001396#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001397private:
1398 promise& operator=(const promise& __rhs);
1399public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001400#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001402 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001403
1404 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001405 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001406
1407 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001408 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001409#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001410 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001411#endif
1412 void set_exception(exception_ptr __p);
1413
1414 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001415 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001416#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001417 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001418#endif
1419 void set_exception_at_thread_exit(exception_ptr __p);
1420};
1421
Howard Hinnantc834c512011-11-29 18:15:50 +00001422template <class _Rp>
1423promise<_Rp>::promise()
1424 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001425{
1426}
1427
Howard Hinnantc834c512011-11-29 18:15:50 +00001428template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001429template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001430promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001431{
Eric Fiselier0d109272014-10-23 06:24:45 +00001432 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1433 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001434 typedef __allocator_destructor<_A2> _D2;
1435 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001436 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1437 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1438 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001439}
1440
Howard Hinnantc834c512011-11-29 18:15:50 +00001441template <class _Rp>
1442promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001443{
1444 if (__state_)
1445 {
1446 if (!__state_->__has_value() && __state_->use_count() > 1)
1447 __state_->set_exception(make_exception_ptr(
1448 future_error(make_error_code(future_errc::broken_promise))
1449 ));
1450 __state_->__release_shared();
1451 }
1452}
1453
Howard Hinnantc834c512011-11-29 18:15:50 +00001454template <class _Rp>
1455future<_Rp>
1456promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001457{
1458 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001459 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001460 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001461}
1462
Howard Hinnantc834c512011-11-29 18:15:50 +00001463template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001464void
Howard Hinnantc834c512011-11-29 18:15:50 +00001465promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001466{
1467 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001468 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001469 __state_->set_value(__r);
1470}
1471
Howard Hinnant74279a52010-09-04 23:28:19 +00001472#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001473
Howard Hinnantc834c512011-11-29 18:15:50 +00001474template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001475void
Howard Hinnantc834c512011-11-29 18:15:50 +00001476promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001477{
1478 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001479 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001480 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001481}
1482
Howard Hinnant74279a52010-09-04 23:28:19 +00001483#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001484
Howard Hinnantc834c512011-11-29 18:15:50 +00001485template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001486void
Howard Hinnantc834c512011-11-29 18:15:50 +00001487promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001488{
Marshall Clow2b36f572016-05-16 16:55:32 +00001489 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001490 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001491 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001492 __state_->set_exception(__p);
1493}
1494
Howard Hinnantc834c512011-11-29 18:15:50 +00001495template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001496void
Howard Hinnantc834c512011-11-29 18:15:50 +00001497promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001498{
1499 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001500 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001501 __state_->set_value_at_thread_exit(__r);
1502}
1503
Howard Hinnant74279a52010-09-04 23:28:19 +00001504#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001505
Howard Hinnantc834c512011-11-29 18:15:50 +00001506template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001507void
Howard Hinnantc834c512011-11-29 18:15:50 +00001508promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001509{
1510 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001511 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001512 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001513}
1514
Howard Hinnant74279a52010-09-04 23:28:19 +00001515#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001516
Howard Hinnantc834c512011-11-29 18:15:50 +00001517template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001518void
Howard Hinnantc834c512011-11-29 18:15:50 +00001519promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001520{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001521 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001522 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001523 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001524 __state_->set_exception_at_thread_exit(__p);
1525}
1526
1527// promise<R&>
1528
Howard Hinnantc834c512011-11-29 18:15:50 +00001529template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001530class _LIBCPP_TEMPLATE_VIS promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001531{
Howard Hinnantc834c512011-11-29 18:15:50 +00001532 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001533
Howard Hinnant684902d2010-09-22 14:16:26 +00001534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001535 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001536
1537 template <class> friend class packaged_task;
1538
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001539public:
1540 promise();
1541 template <class _Allocator>
1542 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001543#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001544 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001545 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001546 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1547 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001548#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001549private:
1550 promise(const promise& __rhs);
1551public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001552#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001553 ~promise();
1554
1555 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001556#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001557 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001558 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001559 {
1560 promise(std::move(__rhs)).swap(*this);
1561 return *this;
1562 }
1563 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001564#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001565private:
1566 promise& operator=(const promise& __rhs);
1567public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001568#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001569 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001570 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001571
1572 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001573 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001574
1575 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001576 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001577 void set_exception(exception_ptr __p);
1578
1579 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001580 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001581 void set_exception_at_thread_exit(exception_ptr __p);
1582};
1583
Howard Hinnantc834c512011-11-29 18:15:50 +00001584template <class _Rp>
1585promise<_Rp&>::promise()
1586 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001587{
1588}
1589
Howard Hinnantc834c512011-11-29 18:15:50 +00001590template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001591template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001592promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001593{
Eric Fiselier0d109272014-10-23 06:24:45 +00001594 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1595 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001596 typedef __allocator_destructor<_A2> _D2;
1597 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001598 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1599 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1600 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001601}
1602
Howard Hinnantc834c512011-11-29 18:15:50 +00001603template <class _Rp>
1604promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001605{
1606 if (__state_)
1607 {
1608 if (!__state_->__has_value() && __state_->use_count() > 1)
1609 __state_->set_exception(make_exception_ptr(
1610 future_error(make_error_code(future_errc::broken_promise))
1611 ));
1612 __state_->__release_shared();
1613 }
1614}
1615
Howard Hinnantc834c512011-11-29 18:15:50 +00001616template <class _Rp>
1617future<_Rp&>
1618promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001619{
1620 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001621 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001622 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001623}
1624
Howard Hinnantc834c512011-11-29 18:15:50 +00001625template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001626void
Howard Hinnantc834c512011-11-29 18:15:50 +00001627promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001628{
1629 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001630 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001631 __state_->set_value(__r);
1632}
1633
Howard Hinnantc834c512011-11-29 18:15:50 +00001634template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001635void
Howard Hinnantc834c512011-11-29 18:15:50 +00001636promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001637{
Marshall Clow2b36f572016-05-16 16:55:32 +00001638 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001639 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001640 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001641 __state_->set_exception(__p);
1642}
1643
Howard Hinnantc834c512011-11-29 18:15:50 +00001644template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001645void
Howard Hinnantc834c512011-11-29 18:15:50 +00001646promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001647{
1648 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001649 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001650 __state_->set_value_at_thread_exit(__r);
1651}
1652
Howard Hinnantc834c512011-11-29 18:15:50 +00001653template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001654void
Howard Hinnantc834c512011-11-29 18:15:50 +00001655promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001656{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001657 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001658 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001659 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001660 __state_->set_exception_at_thread_exit(__p);
1661}
1662
1663// promise<void>
1664
1665template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001666class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001667{
1668 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001669
Howard Hinnant684902d2010-09-22 14:16:26 +00001670 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001671 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001672
1673 template <class> friend class packaged_task;
1674
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001675public:
1676 promise();
1677 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001678 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001679 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001680#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001681 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001682 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001683 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1684 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001685#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001686private:
1687 promise(const promise& __rhs);
1688public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001689#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001690 ~promise();
1691
1692 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001693#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001694 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001695 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001696 {
1697 promise(std::move(__rhs)).swap(*this);
1698 return *this;
1699 }
1700 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001701#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001702private:
1703 promise& operator=(const promise& __rhs);
1704public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001705#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001707 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001708
1709 // retrieving the result
1710 future<void> get_future();
1711
1712 // setting the result
1713 void set_value();
1714 void set_exception(exception_ptr __p);
1715
1716 // setting the result with deferred notification
1717 void set_value_at_thread_exit();
1718 void set_exception_at_thread_exit(exception_ptr __p);
1719};
1720
1721template <class _Alloc>
1722promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1723{
Eric Fiselier0d109272014-10-23 06:24:45 +00001724 typedef __assoc_sub_state_alloc<_Alloc> _State;
1725 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001726 typedef __allocator_destructor<_A2> _D2;
1727 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001728 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1729 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1730 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001731}
1732
Howard Hinnantc834c512011-11-29 18:15:50 +00001733template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001734inline _LIBCPP_INLINE_VISIBILITY
1735void
Howard Hinnant22448042012-07-21 17:46:55 +00001736swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001737{
1738 __x.swap(__y);
1739}
1740
Howard Hinnantc834c512011-11-29 18:15:50 +00001741template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001742 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001743 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001744
Howard Hinnantccdd2032010-08-30 18:46:21 +00001745#ifndef _LIBCPP_HAS_NO_VARIADICS
1746
1747// packaged_task
1748
1749template<class _Fp> class __packaged_task_base;
1750
Howard Hinnantc834c512011-11-29 18:15:50 +00001751template<class _Rp, class ..._ArgTypes>
1752class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001753{
1754 __packaged_task_base(const __packaged_task_base&);
1755 __packaged_task_base& operator=(const __packaged_task_base&);
1756public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001757 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001758 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001759 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001760 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001761 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001762 virtual void destroy() = 0;
1763 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001764 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001765};
1766
1767template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1768
Howard Hinnantc834c512011-11-29 18:15:50 +00001769template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1770class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1771 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001772{
Howard Hinnantc834c512011-11-29 18:15:50 +00001773 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001774public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001776 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001778 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001779 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001780 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001781 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001782 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001783 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001784 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001785 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001786 virtual void destroy();
1787 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001788 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001789};
1790
Howard Hinnantc834c512011-11-29 18:15:50 +00001791template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001792void
Howard Hinnantc834c512011-11-29 18:15:50 +00001793__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001794 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001795{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001796 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001797}
1798
Howard Hinnantc834c512011-11-29 18:15:50 +00001799template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001800void
Howard Hinnantc834c512011-11-29 18:15:50 +00001801__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001802{
Howard Hinnantc834c512011-11-29 18:15:50 +00001803 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001804}
1805
Howard Hinnantc834c512011-11-29 18:15:50 +00001806template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001807void
Howard Hinnantc834c512011-11-29 18:15:50 +00001808__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001809{
Eric Fiselier0d109272014-10-23 06:24:45 +00001810 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1811 typedef allocator_traits<_Ap> _ATraits;
1812 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001813 _Ap __a(__f_.second());
1814 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001815 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001816}
1817
Howard Hinnantc834c512011-11-29 18:15:50 +00001818template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1819_Rp
1820__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001821{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001822 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001823}
1824
Howard Hinnant944510a2011-06-14 19:58:17 +00001825template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001826
Howard Hinnantc834c512011-11-29 18:15:50 +00001827template<class _Rp, class ..._ArgTypes>
1828class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001829{
Howard Hinnantc834c512011-11-29 18:15:50 +00001830 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001831 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001832 __base* __f_;
1833
1834public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001835 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001836
1837 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001838 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001839 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001840 template<class _Fp>
1841 __packaged_task_function(_Fp&& __f);
1842 template<class _Fp, class _Alloc>
1843 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001844
Howard Hinnant22448042012-07-21 17:46:55 +00001845 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1846 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001847
1848 __packaged_task_function(const __packaged_task_function&) = delete;
1849 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1850
1851 ~__packaged_task_function();
1852
Howard Hinnant22448042012-07-21 17:46:55 +00001853 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001854
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001855 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001856 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001857};
1858
Howard Hinnantc834c512011-11-29 18:15:50 +00001859template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001860__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001861{
1862 if (__f.__f_ == nullptr)
1863 __f_ = nullptr;
1864 else if (__f.__f_ == (__base*)&__f.__buf_)
1865 {
1866 __f_ = (__base*)&__buf_;
1867 __f.__f_->__move_to(__f_);
1868 }
1869 else
1870 {
1871 __f_ = __f.__f_;
1872 __f.__f_ = nullptr;
1873 }
1874}
1875
Howard Hinnantc834c512011-11-29 18:15:50 +00001876template<class _Rp, class ..._ArgTypes>
1877template <class _Fp>
1878__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001879 : __f_(nullptr)
1880{
Marshall Clow733d60e2014-04-07 13:32:26 +00001881 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001882 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001883 if (sizeof(_FF) <= sizeof(__buf_))
1884 {
1885 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001886 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001887 }
1888 else
1889 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001890 typedef allocator<_FF> _Ap;
1891 _Ap __a;
1892 typedef __allocator_destructor<_Ap> _Dp;
1893 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1894 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001895 __f_ = __hold.release();
1896 }
1897}
1898
Howard Hinnantc834c512011-11-29 18:15:50 +00001899template<class _Rp, class ..._ArgTypes>
1900template <class _Fp, class _Alloc>
1901__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1902 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001903 : __f_(nullptr)
1904{
Marshall Clow733d60e2014-04-07 13:32:26 +00001905 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001906 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001907 if (sizeof(_FF) <= sizeof(__buf_))
1908 {
1909 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001910 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001911 }
1912 else
1913 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001914 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001915 _Ap __a(__a0);
1916 typedef __allocator_destructor<_Ap> _Dp;
1917 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001918 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1919 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1920 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001921 }
1922}
1923
Howard Hinnantc834c512011-11-29 18:15:50 +00001924template<class _Rp, class ..._ArgTypes>
1925__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001926__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001927{
1928 if (__f_ == (__base*)&__buf_)
1929 __f_->destroy();
1930 else if (__f_)
1931 __f_->destroy_deallocate();
1932 __f_ = nullptr;
1933 if (__f.__f_ == nullptr)
1934 __f_ = nullptr;
1935 else if (__f.__f_ == (__base*)&__f.__buf_)
1936 {
1937 __f_ = (__base*)&__buf_;
1938 __f.__f_->__move_to(__f_);
1939 }
1940 else
1941 {
1942 __f_ = __f.__f_;
1943 __f.__f_ = nullptr;
1944 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001945 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001946}
1947
Howard Hinnantc834c512011-11-29 18:15:50 +00001948template<class _Rp, class ..._ArgTypes>
1949__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001950{
1951 if (__f_ == (__base*)&__buf_)
1952 __f_->destroy();
1953 else if (__f_)
1954 __f_->destroy_deallocate();
1955}
1956
Howard Hinnantc834c512011-11-29 18:15:50 +00001957template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001958void
Howard Hinnant22448042012-07-21 17:46:55 +00001959__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001960{
1961 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1962 {
1963 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1964 __base* __t = (__base*)&__tempbuf;
1965 __f_->__move_to(__t);
1966 __f_->destroy();
1967 __f_ = nullptr;
1968 __f.__f_->__move_to((__base*)&__buf_);
1969 __f.__f_->destroy();
1970 __f.__f_ = nullptr;
1971 __f_ = (__base*)&__buf_;
1972 __t->__move_to((__base*)&__f.__buf_);
1973 __t->destroy();
1974 __f.__f_ = (__base*)&__f.__buf_;
1975 }
1976 else if (__f_ == (__base*)&__buf_)
1977 {
1978 __f_->__move_to((__base*)&__f.__buf_);
1979 __f_->destroy();
1980 __f_ = __f.__f_;
1981 __f.__f_ = (__base*)&__f.__buf_;
1982 }
1983 else if (__f.__f_ == (__base*)&__f.__buf_)
1984 {
1985 __f.__f_->__move_to((__base*)&__buf_);
1986 __f.__f_->destroy();
1987 __f.__f_ = __f_;
1988 __f_ = (__base*)&__buf_;
1989 }
1990 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001991 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001992}
1993
Howard Hinnantc834c512011-11-29 18:15:50 +00001994template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001995inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001996_Rp
1997__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001998{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001999 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002000}
2001
Howard Hinnantc834c512011-11-29 18:15:50 +00002002template<class _Rp, class ..._ArgTypes>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002003class _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004{
2005public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002006 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002007
2008private:
2009 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2010 promise<result_type> __p_;
2011
2012public:
2013 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002015 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002016 template <class _Fp,
2017 class = typename enable_if
2018 <
2019 !is_same<
2020 typename decay<_Fp>::type,
2021 packaged_task
2022 >::value
2023 >::type
2024 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002025 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002026 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002027 template <class _Fp, class _Allocator,
2028 class = typename enable_if
2029 <
2030 !is_same<
2031 typename decay<_Fp>::type,
2032 packaged_task
2033 >::value
2034 >::type
2035 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002036 _LIBCPP_INLINE_VISIBILITY
Marshall Clowc317e022015-06-30 14:16:49 +00002037 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002038 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002039 __p_(allocator_arg, __a) {}
2040 // ~packaged_task() = default;
2041
2042 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002043 packaged_task(const packaged_task&) = delete;
2044 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002045
2046 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002048 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002049 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002050 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002051 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002052 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002053 __f_ = _VSTD::move(__other.__f_);
2054 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002055 return *this;
2056 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002057 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002058 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002059 {
2060 __f_.swap(__other.__f_);
2061 __p_.swap(__other.__p_);
2062 }
2063
Howard Hinnant684902d2010-09-22 14:16:26 +00002064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002065 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002066
2067 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002069 future<result_type> get_future() {return __p_.get_future();}
2070
2071 // execution
2072 void operator()(_ArgTypes... __args);
2073 void make_ready_at_thread_exit(_ArgTypes... __args);
2074
2075 void reset();
2076};
2077
Howard Hinnantc834c512011-11-29 18:15:50 +00002078template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002079void
Howard Hinnantc834c512011-11-29 18:15:50 +00002080packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002082 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002083 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002084 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002085 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002086#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002087 try
2088 {
2089#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002090 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002091#ifndef _LIBCPP_NO_EXCEPTIONS
2092 }
2093 catch (...)
2094 {
2095 __p_.set_exception(current_exception());
2096 }
2097#endif // _LIBCPP_NO_EXCEPTIONS
2098}
2099
Howard Hinnantc834c512011-11-29 18:15:50 +00002100template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002101void
Howard Hinnantc834c512011-11-29 18:15:50 +00002102packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002103{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002104 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002105 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002106 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002107 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002108#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002109 try
2110 {
2111#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002112 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002113#ifndef _LIBCPP_NO_EXCEPTIONS
2114 }
2115 catch (...)
2116 {
2117 __p_.set_exception_at_thread_exit(current_exception());
2118 }
2119#endif // _LIBCPP_NO_EXCEPTIONS
2120}
2121
Howard Hinnantc834c512011-11-29 18:15:50 +00002122template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002123void
Howard Hinnantc834c512011-11-29 18:15:50 +00002124packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002125{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002126 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002127 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002128 __p_ = promise<result_type>();
2129}
2130
2131template<class ..._ArgTypes>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002132class _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002133{
2134public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002135 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002136
2137private:
2138 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2139 promise<result_type> __p_;
2140
2141public:
2142 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002143 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002144 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002145 template <class _Fp,
2146 class = typename enable_if
2147 <
2148 !is_same<
2149 typename decay<_Fp>::type,
2150 packaged_task
2151 >::value
2152 >::type
2153 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002154 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002155 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002156 template <class _Fp, class _Allocator,
2157 class = typename enable_if
2158 <
2159 !is_same<
2160 typename decay<_Fp>::type,
2161 packaged_task
2162 >::value
2163 >::type
2164 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002165 _LIBCPP_INLINE_VISIBILITY
Marshall Clow976e4822015-06-30 18:28:35 +00002166 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002167 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002168 __p_(allocator_arg, __a) {}
2169 // ~packaged_task() = default;
2170
2171 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002172 packaged_task(const packaged_task&) = delete;
2173 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002174
2175 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002177 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002178 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002179 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002180 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002181 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002182 __f_ = _VSTD::move(__other.__f_);
2183 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002184 return *this;
2185 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002186 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002187 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002188 {
2189 __f_.swap(__other.__f_);
2190 __p_.swap(__other.__p_);
2191 }
2192
Howard Hinnant684902d2010-09-22 14:16:26 +00002193 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002194 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002195
2196 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002198 future<result_type> get_future() {return __p_.get_future();}
2199
2200 // execution
2201 void operator()(_ArgTypes... __args);
2202 void make_ready_at_thread_exit(_ArgTypes... __args);
2203
2204 void reset();
2205};
2206
2207template<class ..._ArgTypes>
2208void
2209packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2210{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002211 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002212 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002213 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002214 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002215#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002216 try
2217 {
2218#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002219 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002220 __p_.set_value();
2221#ifndef _LIBCPP_NO_EXCEPTIONS
2222 }
2223 catch (...)
2224 {
2225 __p_.set_exception(current_exception());
2226 }
2227#endif // _LIBCPP_NO_EXCEPTIONS
2228}
2229
2230template<class ..._ArgTypes>
2231void
2232packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2233{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002234 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002235 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002236 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002237 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002238#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002239 try
2240 {
2241#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002242 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002243 __p_.set_value_at_thread_exit();
2244#ifndef _LIBCPP_NO_EXCEPTIONS
2245 }
2246 catch (...)
2247 {
2248 __p_.set_exception_at_thread_exit(current_exception());
2249 }
2250#endif // _LIBCPP_NO_EXCEPTIONS
2251}
2252
2253template<class ..._ArgTypes>
2254void
2255packaged_task<void(_ArgTypes...)>::reset()
2256{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002257 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002258 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002259 __p_ = promise<result_type>();
2260}
2261
2262template <class _Callable>
2263inline _LIBCPP_INLINE_VISIBILITY
2264void
Howard Hinnant22448042012-07-21 17:46:55 +00002265swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002266{
2267 __x.swap(__y);
2268}
2269
2270template <class _Callable, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002271struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00002272 : public true_type {};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002273
Howard Hinnantc834c512011-11-29 18:15:50 +00002274template <class _Rp, class _Fp>
2275future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002276#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002277__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002278#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002279__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002280#endif
2281{
Howard Hinnantc834c512011-11-29 18:15:50 +00002282 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2283 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2284 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002285}
2286
Howard Hinnantc834c512011-11-29 18:15:50 +00002287template <class _Rp, class _Fp>
2288future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002289#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002290__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002291#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002292__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002293#endif
2294{
Howard Hinnantc834c512011-11-29 18:15:50 +00002295 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2296 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2297 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2298 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002299}
2300
Howard Hinnantc834c512011-11-29 18:15:50 +00002301template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002302class __async_func
2303{
Howard Hinnantc834c512011-11-29 18:15:50 +00002304 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002305
2306public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002307 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002308
2309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002310 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002311 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002312
2313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002314 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002315
Howard Hinnantc834c512011-11-29 18:15:50 +00002316 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002317 {
2318 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2319 return __execute(_Index());
2320 }
2321private:
2322 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002323 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002324 __execute(__tuple_indices<_Indices...>)
2325 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002326 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002327 }
2328};
2329
Marshall Clowd56a5b62013-11-03 22:06:53 +00002330inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002331{ return (int(__policy) & int(__value)) != 0; }
2332
Howard Hinnantc834c512011-11-29 18:15:50 +00002333template <class _Fp, class... _Args>
2334future<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>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002359inline _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 <>
Howard Hinnant8331b762013-03-06 23:30:19 +00002520class _LIBCPP_TYPE_VIS 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