blob: 936060e173b8336fcdbbb032e7bc7ae2383de4d3 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-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 Hinnantbc8d3f92010-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 Hinnantcd942f12013-09-14 18:20:10 +000022 future_already_retrieved = 1,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000023 promise_already_satisfied,
Howard Hinnantcd942f12013-09-14 18:20:10 +000024 no_state,
25 broken_promise
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000026};
27
28enum class launch
29{
Howard Hinnant66895642010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000045
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000311template <class F, class... Args>
Howard Hinnant0836f872013-09-21 18:17:23 +0000312 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
Howard Hinnant0836f872013-09-21 18:17:23 +0000316 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantf5256e12010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
Eric Fiselier68db6cd2016-06-01 21:05:53 +0000325 typedef R result_type; // extension
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000326
327 // construction and destruction
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
Marshall Clow07546f32015-06-30 14:16:49 +0000332 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000333 ~packaged_task();
334
335 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant8bf01dd2012-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000343
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantbc8d3f92010-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 Hinnant47499b12010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372
Howard Hinnant08e17472011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000375#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376
Jonathan Roelofsbaed05d2014-09-05 20:28:44 +0000377#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +0000378#error <future> is not supported on this single threaded system
379#else // !_LIBCPP_HAS_NO_THREADS
380
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381_LIBCPP_BEGIN_NAMESPACE_STD
382
383//enum class future_errc
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000384_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000385{
Howard Hinnantcd942f12013-09-14 18:20:10 +0000386 future_already_retrieved = 1,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000387 promise_already_satisfied,
Howard Hinnantcd942f12013-09-14 18:20:10 +0000388 no_state,
389 broken_promise
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000390};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000391_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000392
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000393template <>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000394struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000395
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000396#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397template <>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000398struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000399#endif
400
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401//enum class launch
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000402_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403{
Howard Hinnant66895642010-11-23 18:33:54 +0000404 async = 1,
405 deferred = 2,
406 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000407};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409
Howard Hinnantf491e512013-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 Hinnant6a683bf2013-07-02 18:01:41 +0000450 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantf491e512013-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 Hinnantbc8d3f92010-05-11 19:42:16 +0000476//enum class future_status
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000477_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000478{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000479 ready,
480 timeout,
481 deferred
482};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000483_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000484
Howard Hinnant83eade62013-03-06 23:30:19 +0000485_LIBCPP_FUNC_VIS
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000486const error_category& future_category() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000487
488inline _LIBCPP_INLINE_VISIBILITY
489error_code
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000490make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-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 Hinnant8bf01dd2012-07-21 17:46:55 +0000497make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000498{
499 return error_condition(static_cast<int>(__e), future_category());
500}
501
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000502class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000503 : public logic_error
504{
505 error_code __ec_;
506public:
507 future_error(error_code __ec);
508
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000509 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000510 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52 +0000511
512 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000513};
514
Eric Fiselier423ca202015-10-02 21:25:15 +0000515inline _LIBCPP_ALWAYS_INLINE
516void __throw_future_error(future_errc _Ev)
Marshall Clowa1899742015-09-03 15:11:32 +0000517{
518#ifndef _LIBCPP_NO_EXCEPTIONS
519 throw future_error(make_error_code(_Ev));
520#else
521 assert(!"future_error");
522#endif
523}
524
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000525class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant47499b12010-08-27 20:10:19 +0000526 : public __shared_count
527{
528protected:
529 exception_ptr __exception_;
530 mutable mutex __mut_;
531 mutable condition_variable __cv_;
532 unsigned __state_;
533
Howard Hinnant1694d232011-05-28 14:41:13 +0000534 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000535 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000536public:
537 enum
538 {
539 __constructed = 1,
540 __future_attached = 2,
541 ready = 4,
542 deferred = 8
543 };
544
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000545 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000546 __assoc_sub_state() : __state_(0) {}
547
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000549 bool __has_value() const
550 {return (__state_ & __constructed) || (__exception_ != nullptr);}
551
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1b031c92013-01-14 20:01:24 +0000553 void __set_future_attached()
554 {
555 lock_guard<mutex> __lk(__mut_);
556 __state_ |= __future_attached;
557 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000558 _LIBCPP_INLINE_VISIBILITY
Marshall Clow9de3d4c2013-10-13 01:02:45 +0000559 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant47499b12010-08-27 20:10:19 +0000560
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000562 void __set_deferred() {__state_ |= deferred;}
563
Howard Hinnant47499b12010-08-27 20:10:19 +0000564 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000565 _LIBCPP_INLINE_VISIBILITY
Marshall Clow9de3d4c2013-10-13 01:02:45 +0000566 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant47499b12010-08-27 20:10:19 +0000567
568 void set_value();
569 void set_value_at_thread_exit();
570
571 void set_exception(exception_ptr __p);
572 void set_exception_at_thread_exit(exception_ptr __p);
573
574 void copy();
575
Howard Hinnant54da3382010-08-30 18:46:21 +0000576 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000577 template <class _Rep, class _Period>
578 future_status
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000580 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
581 template <class _Clock, class _Duration>
582 future_status
583 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000584
585 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000586};
587
Howard Hinnantf39daa82010-08-28 21:01:06 +0000588template <class _Clock, class _Duration>
589future_status
590__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
591{
592 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000593 if (__state_ & deferred)
594 return future_status::deferred;
595 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000596 __cv_.wait_until(__lk, __abs_time);
597 if (__state_ & ready)
598 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000599 return future_status::timeout;
600}
601
602template <class _Rep, class _Period>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000603inline
Howard Hinnantf39daa82010-08-28 21:01:06 +0000604future_status
605__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
606{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000607 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000608}
609
Howard Hinnant99968442011-11-29 18:15:50 +0000610template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000611class __assoc_state
612 : public __assoc_sub_state
613{
614 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000615 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000616protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000617 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000618
Howard Hinnant1694d232011-05-28 14:41:13 +0000619 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000620public:
621
622 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000623#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000624 void set_value(_Arg&& __arg);
625#else
626 void set_value(_Arg& __arg);
627#endif
628
629 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000630#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000631 void set_value_at_thread_exit(_Arg&& __arg);
632#else
633 void set_value_at_thread_exit(_Arg& __arg);
634#endif
635
Howard Hinnant99968442011-11-29 18:15:50 +0000636 _Rp move();
637 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000638};
639
Howard Hinnant99968442011-11-29 18:15:50 +0000640template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000641void
Howard Hinnant99968442011-11-29 18:15:50 +0000642__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000643{
644 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000645 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000646 delete this;
647}
648
Howard Hinnant99968442011-11-29 18:15:50 +0000649template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000650template <class _Arg>
651void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000652#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000653__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000654#else
Howard Hinnant99968442011-11-29 18:15:50 +0000655__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000656#endif
657{
658 unique_lock<mutex> __lk(this->__mut_);
659 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000660 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant99968442011-11-29 18:15:50 +0000661 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000662 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant47499b12010-08-27 20:10:19 +0000663 __cv_.notify_all();
664}
665
Howard Hinnant99968442011-11-29 18:15:50 +0000666template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000667template <class _Arg>
668void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000669#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000670__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000671#else
Howard Hinnant99968442011-11-29 18:15:50 +0000672__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000673#endif
674{
675 unique_lock<mutex> __lk(this->__mut_);
676 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000677 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant99968442011-11-29 18:15:50 +0000678 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000679 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000680 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000681}
682
Howard Hinnant99968442011-11-29 18:15:50 +0000683template <class _Rp>
684_Rp
685__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000686{
687 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000688 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000689 if (this->__exception_ != nullptr)
690 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000691 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000692}
693
Howard Hinnant99968442011-11-29 18:15:50 +0000694template <class _Rp>
695typename add_lvalue_reference<_Rp>::type
696__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000697{
698 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000699 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000700 if (this->__exception_ != nullptr)
701 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000702 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000703}
704
Howard Hinnant99968442011-11-29 18:15:50 +0000705template <class _Rp>
706class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000707 : public __assoc_sub_state
708{
709 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000710 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000711protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000712 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000713
Howard Hinnant1694d232011-05-28 14:41:13 +0000714 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000715public:
716
Howard Hinnant99968442011-11-29 18:15:50 +0000717 void set_value(_Rp& __arg);
718 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000719
Howard Hinnant99968442011-11-29 18:15:50 +0000720 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000721};
722
Howard Hinnant99968442011-11-29 18:15:50 +0000723template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000724void
Howard Hinnant99968442011-11-29 18:15:50 +0000725__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000726{
727 delete this;
728}
729
Howard Hinnant99968442011-11-29 18:15:50 +0000730template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000731void
Howard Hinnant99968442011-11-29 18:15:50 +0000732__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000733{
734 unique_lock<mutex> __lk(this->__mut_);
735 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000736 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000737 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000738 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000739 __cv_.notify_all();
740}
741
Howard Hinnant99968442011-11-29 18:15:50 +0000742template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000743void
Howard Hinnant99968442011-11-29 18:15:50 +0000744__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000745{
746 unique_lock<mutex> __lk(this->__mut_);
747 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000748 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000749 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000750 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000751 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000752}
753
Howard Hinnant99968442011-11-29 18:15:50 +0000754template <class _Rp>
755_Rp&
756__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000757{
758 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000759 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000760 if (this->__exception_ != nullptr)
761 rethrow_exception(this->__exception_);
762 return *__value_;
763}
764
Howard Hinnant99968442011-11-29 18:15:50 +0000765template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000766class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000767 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000768{
Howard Hinnant99968442011-11-29 18:15:50 +0000769 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000770 _Alloc __alloc_;
771
Howard Hinnant1694d232011-05-28 14:41:13 +0000772 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000773public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000775 explicit __assoc_state_alloc(const _Alloc& __a)
776 : __alloc_(__a) {}
777};
778
Howard Hinnant99968442011-11-29 18:15:50 +0000779template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000780void
Howard Hinnant99968442011-11-29 18:15:50 +0000781__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000782{
783 if (this->__state_ & base::__constructed)
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000784 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselier8492cd82015-02-05 23:01:40 +0000785 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
786 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000787 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000788 _Al __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000789 this->~__assoc_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000790 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant47499b12010-08-27 20:10:19 +0000791}
792
Howard Hinnant99968442011-11-29 18:15:50 +0000793template <class _Rp, class _Alloc>
794class __assoc_state_alloc<_Rp&, _Alloc>
795 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000796{
Howard Hinnant99968442011-11-29 18:15:50 +0000797 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000798 _Alloc __alloc_;
799
Howard Hinnant1694d232011-05-28 14:41:13 +0000800 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000801public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000802 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000803 explicit __assoc_state_alloc(const _Alloc& __a)
804 : __alloc_(__a) {}
805};
806
Howard Hinnant99968442011-11-29 18:15:50 +0000807template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000808void
Howard Hinnant99968442011-11-29 18:15:50 +0000809__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000810{
Eric Fiselier8492cd82015-02-05 23:01:40 +0000811 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
812 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000813 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000814 _Al __a(__alloc_);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000815 this->~__assoc_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000816 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000817}
818
Howard Hinnant47499b12010-08-27 20:10:19 +0000819template <class _Alloc>
820class __assoc_sub_state_alloc
821 : public __assoc_sub_state
822{
823 typedef __assoc_sub_state base;
824 _Alloc __alloc_;
825
Howard Hinnant1694d232011-05-28 14:41:13 +0000826 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000827public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000828 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000829 explicit __assoc_sub_state_alloc(const _Alloc& __a)
830 : __alloc_(__a) {}
831};
832
833template <class _Alloc>
834void
Howard Hinnant1694d232011-05-28 14:41:13 +0000835__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000836{
Eric Fiselier8492cd82015-02-05 23:01:40 +0000837 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
838 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000839 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000840 _Al __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000841 this->~__assoc_sub_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000842 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant47499b12010-08-27 20:10:19 +0000843}
844
Howard Hinnant99968442011-11-29 18:15:50 +0000845template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000846class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000847 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000848{
Howard Hinnant99968442011-11-29 18:15:50 +0000849 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000850
Howard Hinnant99968442011-11-29 18:15:50 +0000851 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000852
853public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000854#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000855 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000856 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000857#endif
858
859 virtual void __execute();
860};
861
Howard Hinnant73d21a42010-09-04 23:28:19 +0000862#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000863
Howard Hinnant99968442011-11-29 18:15:50 +0000864template <class _Rp, class _Fp>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000865inline
Howard Hinnant99968442011-11-29 18:15:50 +0000866__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
867 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000868{
869 this->__set_deferred();
870}
871
Howard Hinnant73d21a42010-09-04 23:28:19 +0000872#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000873
Howard Hinnant99968442011-11-29 18:15:50 +0000874template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000875void
Howard Hinnant99968442011-11-29 18:15:50 +0000876__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000877{
878#ifndef _LIBCPP_NO_EXCEPTIONS
879 try
880 {
881#endif // _LIBCPP_NO_EXCEPTIONS
882 this->set_value(__func_());
883#ifndef _LIBCPP_NO_EXCEPTIONS
884 }
885 catch (...)
886 {
887 this->set_exception(current_exception());
888 }
889#endif // _LIBCPP_NO_EXCEPTIONS
890}
891
Howard Hinnant99968442011-11-29 18:15:50 +0000892template <class _Fp>
893class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000894 : public __assoc_sub_state
895{
896 typedef __assoc_sub_state base;
897
Howard Hinnant99968442011-11-29 18:15:50 +0000898 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000899
900public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000901#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000902 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000903 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000904#endif
905
906 virtual void __execute();
907};
908
Howard Hinnant73d21a42010-09-04 23:28:19 +0000909#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000910
Howard Hinnant99968442011-11-29 18:15:50 +0000911template <class _Fp>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000912inline
Howard Hinnant99968442011-11-29 18:15:50 +0000913__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
914 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000915{
916 this->__set_deferred();
917}
918
Howard Hinnant73d21a42010-09-04 23:28:19 +0000919#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000920
Howard Hinnant99968442011-11-29 18:15:50 +0000921template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000922void
Howard Hinnant99968442011-11-29 18:15:50 +0000923__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000924{
925#ifndef _LIBCPP_NO_EXCEPTIONS
926 try
927 {
928#endif // _LIBCPP_NO_EXCEPTIONS
929 __func_();
930 this->set_value();
931#ifndef _LIBCPP_NO_EXCEPTIONS
932 }
933 catch (...)
934 {
935 this->set_exception(current_exception());
936 }
937#endif // _LIBCPP_NO_EXCEPTIONS
938}
939
Howard Hinnant99968442011-11-29 18:15:50 +0000940template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000941class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000942 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000943{
Howard Hinnant99968442011-11-29 18:15:50 +0000944 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000945
Howard Hinnant99968442011-11-29 18:15:50 +0000946 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000947
Howard Hinnant1694d232011-05-28 14:41:13 +0000948 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000949public:
950#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000951 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000952 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000953#endif
954
955 virtual void __execute();
956};
957
958#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
959
Howard Hinnant99968442011-11-29 18:15:50 +0000960template <class _Rp, class _Fp>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000961inline
Howard Hinnant99968442011-11-29 18:15:50 +0000962__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
963 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000964{
965}
966
967#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
968
Howard Hinnant99968442011-11-29 18:15:50 +0000969template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000970void
Howard Hinnant99968442011-11-29 18:15:50 +0000971__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000972{
973#ifndef _LIBCPP_NO_EXCEPTIONS
974 try
975 {
976#endif // _LIBCPP_NO_EXCEPTIONS
977 this->set_value(__func_());
978#ifndef _LIBCPP_NO_EXCEPTIONS
979 }
980 catch (...)
981 {
982 this->set_exception(current_exception());
983 }
984#endif // _LIBCPP_NO_EXCEPTIONS
985}
986
Howard Hinnant99968442011-11-29 18:15:50 +0000987template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000988void
Howard Hinnant99968442011-11-29 18:15:50 +0000989__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000990{
991 this->wait();
992 base::__on_zero_shared();
993}
994
Howard Hinnant99968442011-11-29 18:15:50 +0000995template <class _Fp>
996class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000997 : public __assoc_sub_state
998{
999 typedef __assoc_sub_state base;
1000
Howard Hinnant99968442011-11-29 18:15:50 +00001001 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +00001002
Howard Hinnant1694d232011-05-28 14:41:13 +00001003 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +00001004public:
1005#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00001006 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001007 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001008#endif
1009
1010 virtual void __execute();
1011};
1012
1013#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1014
Howard Hinnant99968442011-11-29 18:15:50 +00001015template <class _Fp>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00001016inline
Howard Hinnant99968442011-11-29 18:15:50 +00001017__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1018 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +00001019{
1020}
1021
1022#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1023
Howard Hinnant99968442011-11-29 18:15:50 +00001024template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001025void
Howard Hinnant99968442011-11-29 18:15:50 +00001026__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +00001027{
1028#ifndef _LIBCPP_NO_EXCEPTIONS
1029 try
1030 {
1031#endif // _LIBCPP_NO_EXCEPTIONS
1032 __func_();
1033 this->set_value();
1034#ifndef _LIBCPP_NO_EXCEPTIONS
1035 }
1036 catch (...)
1037 {
1038 this->set_exception(current_exception());
1039 }
1040#endif // _LIBCPP_NO_EXCEPTIONS
1041}
1042
Howard Hinnant99968442011-11-29 18:15:50 +00001043template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001044void
Howard Hinnant99968442011-11-29 18:15:50 +00001045__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +00001046{
1047 this->wait();
1048 base::__on_zero_shared();
1049}
1050
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001051template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1052template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +00001053
1054// future
1055
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001056template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001057
Howard Hinnant99968442011-11-29 18:15:50 +00001058template <class _Rp, class _Fp>
1059future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001060#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001061__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001062#else
Howard Hinnant99968442011-11-29 18:15:50 +00001063__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001064#endif
1065
Howard Hinnant99968442011-11-29 18:15:50 +00001066template <class _Rp, class _Fp>
1067future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001068#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001069__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001070#else
Howard Hinnant99968442011-11-29 18:15:50 +00001071__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001072#endif
1073
Howard Hinnant99968442011-11-29 18:15:50 +00001074template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001075class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant47499b12010-08-27 20:10:19 +00001076{
Howard Hinnant99968442011-11-29 18:15:50 +00001077 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001078
Howard Hinnant99968442011-11-29 18:15:50 +00001079 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001080
1081 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001082 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001083
Howard Hinnant73d21a42010-09-04 23:28:19 +00001084#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001085 template <class _R1, class _Fp>
1086 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1087 template <class _R1, class _Fp>
1088 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001089#else
Howard Hinnant99968442011-11-29 18:15:50 +00001090 template <class _R1, class _Fp>
1091 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1092 template <class _R1, class _Fp>
1093 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001094#endif
1095
Howard Hinnant47499b12010-08-27 20:10:19 +00001096public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001098 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001099#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001100 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001101 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001102 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1103 future(const future&) = delete;
1104 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001105 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001106 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001107 {
1108 future(std::move(__rhs)).swap(*this);
1109 return *this;
1110 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001111#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001112private:
1113 future(const future&);
1114 future& operator=(const future&);
1115public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001116#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001117 ~future();
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00001118 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001119 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001120
1121 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001122 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001123
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001124 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001125 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001126
1127 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001128 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001129 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001130
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001131 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001132 void wait() const {__state_->wait();}
1133 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001134 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001135 future_status
1136 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1137 {return __state_->wait_for(__rel_time);}
1138 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001139 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001140 future_status
1141 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1142 {return __state_->wait_until(__abs_time);}
1143};
1144
Howard Hinnant99968442011-11-29 18:15:50 +00001145template <class _Rp>
1146future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001147 : __state_(__state)
1148{
1149 if (__state_->__has_future_attached())
Eric Fiselier423ca202015-10-02 21:25:15 +00001150 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant47499b12010-08-27 20:10:19 +00001151 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001152 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001153}
1154
Howard Hinnant54da3382010-08-30 18:46:21 +00001155struct __release_shared_count
1156{
1157 void operator()(__shared_count* p) {p->__release_shared();}
1158};
1159
Howard Hinnant99968442011-11-29 18:15:50 +00001160template <class _Rp>
1161future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001162{
1163 if (__state_)
1164 __state_->__release_shared();
1165}
1166
Howard Hinnant99968442011-11-29 18:15:50 +00001167template <class _Rp>
1168_Rp
1169future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001170{
Howard Hinnant54da3382010-08-30 18:46:21 +00001171 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001172 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001173 __state_ = nullptr;
1174 return __s->move();
1175}
1176
Howard Hinnant99968442011-11-29 18:15:50 +00001177template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001178class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001179{
Howard Hinnant99968442011-11-29 18:15:50 +00001180 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001181
Howard Hinnant99968442011-11-29 18:15:50 +00001182 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001183
1184 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001185 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001186
Howard Hinnant73d21a42010-09-04 23:28:19 +00001187#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001188 template <class _R1, class _Fp>
1189 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1190 template <class _R1, class _Fp>
1191 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001192#else
Howard Hinnant99968442011-11-29 18:15:50 +00001193 template <class _R1, class _Fp>
1194 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1195 template <class _R1, class _Fp>
1196 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001197#endif
1198
Howard Hinnant47499b12010-08-27 20:10:19 +00001199public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001200 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001201 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001202#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001203 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001204 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001205 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1206 future(const future&) = delete;
1207 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001208 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001209 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001210 {
1211 future(std::move(__rhs)).swap(*this);
1212 return *this;
1213 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001214#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001215private:
1216 future(const future&);
1217 future& operator=(const future&);
1218public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001219#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001220 ~future();
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00001221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001222 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001223
1224 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001225 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001226
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001227 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001228 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001229
1230 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001232 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001233
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001235 void wait() const {__state_->wait();}
1236 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001238 future_status
1239 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1240 {return __state_->wait_for(__rel_time);}
1241 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001243 future_status
1244 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1245 {return __state_->wait_until(__abs_time);}
1246};
1247
Howard Hinnant99968442011-11-29 18:15:50 +00001248template <class _Rp>
1249future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001250 : __state_(__state)
1251{
1252 if (__state_->__has_future_attached())
Eric Fiselier423ca202015-10-02 21:25:15 +00001253 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant47499b12010-08-27 20:10:19 +00001254 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001255 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001256}
1257
Howard Hinnant99968442011-11-29 18:15:50 +00001258template <class _Rp>
1259future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001260{
1261 if (__state_)
1262 __state_->__release_shared();
1263}
1264
Howard Hinnant99968442011-11-29 18:15:50 +00001265template <class _Rp>
1266_Rp&
1267future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001268{
Howard Hinnant54da3382010-08-30 18:46:21 +00001269 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001270 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001271 __state_ = nullptr;
1272 return __s->copy();
1273}
1274
1275template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001276class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001277{
1278 __assoc_sub_state* __state_;
1279
1280 explicit future(__assoc_sub_state* __state);
1281
1282 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001283 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001284
Howard Hinnant73d21a42010-09-04 23:28:19 +00001285#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001286 template <class _R1, class _Fp>
1287 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1288 template <class _R1, class _Fp>
1289 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001290#else
Howard Hinnant99968442011-11-29 18:15:50 +00001291 template <class _R1, class _Fp>
1292 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1293 template <class _R1, class _Fp>
1294 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001295#endif
1296
Howard Hinnant47499b12010-08-27 20:10:19 +00001297public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001298 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001299 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001300#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001302 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001303 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1304 future(const future&) = delete;
1305 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001306 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001307 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001308 {
1309 future(std::move(__rhs)).swap(*this);
1310 return *this;
1311 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001312#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001313private:
1314 future(const future&);
1315 future& operator=(const future&);
1316public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001317#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001318 ~future();
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00001319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00001320 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001321
1322 // retrieving the value
1323 void get();
1324
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001326 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001327
1328 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001330 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001331
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001333 void wait() const {__state_->wait();}
1334 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001335 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001336 future_status
1337 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1338 {return __state_->wait_for(__rel_time);}
1339 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001340 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001341 future_status
1342 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1343 {return __state_->wait_until(__abs_time);}
1344};
1345
Howard Hinnant99968442011-11-29 18:15:50 +00001346template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001347inline _LIBCPP_INLINE_VISIBILITY
1348void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001349swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00001350{
1351 __x.swap(__y);
1352}
1353
Howard Hinnant47499b12010-08-27 20:10:19 +00001354// promise<R>
1355
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001356template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001357
Howard Hinnant99968442011-11-29 18:15:50 +00001358template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001359class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001360{
Howard Hinnant99968442011-11-29 18:15:50 +00001361 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001362
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001363 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001364 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001365
1366 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001367public:
1368 promise();
1369 template <class _Alloc>
1370 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001371#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001372 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001373 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001374 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1375 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001376#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001377private:
1378 promise(const promise& __rhs);
1379public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001380#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001381 ~promise();
1382
1383 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001384#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001386 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001387 {
1388 promise(std::move(__rhs)).swap(*this);
1389 return *this;
1390 }
1391 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001392#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001393private:
1394 promise& operator=(const promise& __rhs);
1395public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001396#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001397 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001398 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001399
1400 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001401 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001402
1403 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001404 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001405#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001406 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001407#endif
1408 void set_exception(exception_ptr __p);
1409
1410 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001411 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001412#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001413 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001414#endif
1415 void set_exception_at_thread_exit(exception_ptr __p);
1416};
1417
Howard Hinnant99968442011-11-29 18:15:50 +00001418template <class _Rp>
1419promise<_Rp>::promise()
1420 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001421{
1422}
1423
Howard Hinnant99968442011-11-29 18:15:50 +00001424template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001425template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001426promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001427{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001428 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1429 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001430 typedef __allocator_destructor<_A2> _D2;
1431 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001432 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1433 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1434 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001435}
1436
Howard Hinnant99968442011-11-29 18:15:50 +00001437template <class _Rp>
1438promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001439{
1440 if (__state_)
1441 {
1442 if (!__state_->__has_value() && __state_->use_count() > 1)
1443 __state_->set_exception(make_exception_ptr(
1444 future_error(make_error_code(future_errc::broken_promise))
1445 ));
1446 __state_->__release_shared();
1447 }
1448}
1449
Howard Hinnant99968442011-11-29 18:15:50 +00001450template <class _Rp>
1451future<_Rp>
1452promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001453{
1454 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001455 __throw_future_error(future_errc::no_state);
Howard Hinnant99968442011-11-29 18:15:50 +00001456 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001457}
1458
Howard Hinnant99968442011-11-29 18:15:50 +00001459template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001460void
Howard Hinnant99968442011-11-29 18:15:50 +00001461promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001462{
1463 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001464 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001465 __state_->set_value(__r);
1466}
1467
Howard Hinnant73d21a42010-09-04 23:28:19 +00001468#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001469
Howard Hinnant99968442011-11-29 18:15:50 +00001470template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001471void
Howard Hinnant99968442011-11-29 18:15:50 +00001472promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001473{
1474 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001475 __throw_future_error(future_errc::no_state);
Howard Hinnant0949eed2011-06-30 21:18:19 +00001476 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001477}
1478
Howard Hinnant73d21a42010-09-04 23:28:19 +00001479#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001480
Howard Hinnant99968442011-11-29 18:15:50 +00001481template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001482void
Howard Hinnant99968442011-11-29 18:15:50 +00001483promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001484{
Marshall Cloweaba7bb2016-05-16 16:55:32 +00001485 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant47499b12010-08-27 20:10:19 +00001486 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001487 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001488 __state_->set_exception(__p);
1489}
1490
Howard Hinnant99968442011-11-29 18:15:50 +00001491template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001492void
Howard Hinnant99968442011-11-29 18:15:50 +00001493promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001494{
1495 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001496 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001497 __state_->set_value_at_thread_exit(__r);
1498}
1499
Howard Hinnant73d21a42010-09-04 23:28:19 +00001500#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001501
Howard Hinnant99968442011-11-29 18:15:50 +00001502template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001503void
Howard Hinnant99968442011-11-29 18:15:50 +00001504promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001505{
1506 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001507 __throw_future_error(future_errc::no_state);
Howard Hinnant0949eed2011-06-30 21:18:19 +00001508 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001509}
1510
Howard Hinnant73d21a42010-09-04 23:28:19 +00001511#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001512
Howard Hinnant99968442011-11-29 18:15:50 +00001513template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001514void
Howard Hinnant99968442011-11-29 18:15:50 +00001515promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001516{
Eric Fiselierb169bb02016-05-31 01:50:55 +00001517 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant47499b12010-08-27 20:10:19 +00001518 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001519 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001520 __state_->set_exception_at_thread_exit(__p);
1521}
1522
1523// promise<R&>
1524
Howard Hinnant99968442011-11-29 18:15:50 +00001525template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001526class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001527{
Howard Hinnant99968442011-11-29 18:15:50 +00001528 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001529
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001531 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001532
1533 template <class> friend class packaged_task;
1534
Howard Hinnant47499b12010-08-27 20:10:19 +00001535public:
1536 promise();
1537 template <class _Allocator>
1538 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001539#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001541 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001542 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1543 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001544#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001545private:
1546 promise(const promise& __rhs);
1547public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001548#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001549 ~promise();
1550
1551 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001552#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001553 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001554 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001555 {
1556 promise(std::move(__rhs)).swap(*this);
1557 return *this;
1558 }
1559 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001560#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001561private:
1562 promise& operator=(const promise& __rhs);
1563public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001564#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001566 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001567
1568 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001569 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001570
1571 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001572 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001573 void set_exception(exception_ptr __p);
1574
1575 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001576 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001577 void set_exception_at_thread_exit(exception_ptr __p);
1578};
1579
Howard Hinnant99968442011-11-29 18:15:50 +00001580template <class _Rp>
1581promise<_Rp&>::promise()
1582 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001583{
1584}
1585
Howard Hinnant99968442011-11-29 18:15:50 +00001586template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001587template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001588promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001589{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001590 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1591 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001592 typedef __allocator_destructor<_A2> _D2;
1593 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001594 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1595 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1596 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001597}
1598
Howard Hinnant99968442011-11-29 18:15:50 +00001599template <class _Rp>
1600promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001601{
1602 if (__state_)
1603 {
1604 if (!__state_->__has_value() && __state_->use_count() > 1)
1605 __state_->set_exception(make_exception_ptr(
1606 future_error(make_error_code(future_errc::broken_promise))
1607 ));
1608 __state_->__release_shared();
1609 }
1610}
1611
Howard Hinnant99968442011-11-29 18:15:50 +00001612template <class _Rp>
1613future<_Rp&>
1614promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001615{
1616 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001617 __throw_future_error(future_errc::no_state);
Howard Hinnant99968442011-11-29 18:15:50 +00001618 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001619}
1620
Howard Hinnant99968442011-11-29 18:15:50 +00001621template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001622void
Howard Hinnant99968442011-11-29 18:15:50 +00001623promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001624{
1625 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001626 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001627 __state_->set_value(__r);
1628}
1629
Howard Hinnant99968442011-11-29 18:15:50 +00001630template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001631void
Howard Hinnant99968442011-11-29 18:15:50 +00001632promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001633{
Marshall Cloweaba7bb2016-05-16 16:55:32 +00001634 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant47499b12010-08-27 20:10:19 +00001635 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001636 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001637 __state_->set_exception(__p);
1638}
1639
Howard Hinnant99968442011-11-29 18:15:50 +00001640template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001641void
Howard Hinnant99968442011-11-29 18:15:50 +00001642promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001643{
1644 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001645 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001646 __state_->set_value_at_thread_exit(__r);
1647}
1648
Howard Hinnant99968442011-11-29 18:15:50 +00001649template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001650void
Howard Hinnant99968442011-11-29 18:15:50 +00001651promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001652{
Eric Fiselierb169bb02016-05-31 01:50:55 +00001653 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant47499b12010-08-27 20:10:19 +00001654 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001655 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001656 __state_->set_exception_at_thread_exit(__p);
1657}
1658
1659// promise<void>
1660
1661template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001662class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001663{
1664 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001665
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001666 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001667 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001668
1669 template <class> friend class packaged_task;
1670
Howard Hinnant47499b12010-08-27 20:10:19 +00001671public:
1672 promise();
1673 template <class _Allocator>
1674 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001675#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001676 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001677 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001678 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1679 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001680#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001681private:
1682 promise(const promise& __rhs);
1683public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001684#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001685 ~promise();
1686
1687 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001688#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001689 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001690 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001691 {
1692 promise(std::move(__rhs)).swap(*this);
1693 return *this;
1694 }
1695 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001696#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001697private:
1698 promise& operator=(const promise& __rhs);
1699public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001700#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001702 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001703
1704 // retrieving the result
1705 future<void> get_future();
1706
1707 // setting the result
1708 void set_value();
1709 void set_exception(exception_ptr __p);
1710
1711 // setting the result with deferred notification
1712 void set_value_at_thread_exit();
1713 void set_exception_at_thread_exit(exception_ptr __p);
1714};
1715
1716template <class _Alloc>
1717promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1718{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001719 typedef __assoc_sub_state_alloc<_Alloc> _State;
1720 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001721 typedef __allocator_destructor<_A2> _D2;
1722 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001723 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1724 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1725 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001726}
1727
Howard Hinnant99968442011-11-29 18:15:50 +00001728template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001729inline _LIBCPP_INLINE_VISIBILITY
1730void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001731swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001732{
1733 __x.swap(__y);
1734}
1735
Howard Hinnant99968442011-11-29 18:15:50 +00001736template <class _Rp, class _Alloc>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001737 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001738 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001739
Howard Hinnant54da3382010-08-30 18:46:21 +00001740#ifndef _LIBCPP_HAS_NO_VARIADICS
1741
1742// packaged_task
1743
1744template<class _Fp> class __packaged_task_base;
1745
Howard Hinnant99968442011-11-29 18:15:50 +00001746template<class _Rp, class ..._ArgTypes>
1747class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001748{
1749 __packaged_task_base(const __packaged_task_base&);
1750 __packaged_task_base& operator=(const __packaged_task_base&);
1751public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001752 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001753 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001755 virtual ~__packaged_task_base() {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001756 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001757 virtual void destroy() = 0;
1758 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001759 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001760};
1761
1762template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1763
Howard Hinnant99968442011-11-29 18:15:50 +00001764template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1765class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1766 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001767{
Howard Hinnant99968442011-11-29 18:15:50 +00001768 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001769public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001770 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001771 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001773 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001775 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001776 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001778 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001779 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001780 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001781 virtual void destroy();
1782 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001783 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001784};
1785
Howard Hinnant99968442011-11-29 18:15:50 +00001786template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001787void
Howard Hinnant99968442011-11-29 18:15:50 +00001788__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001789 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001790{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001791 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001792}
1793
Howard Hinnant99968442011-11-29 18:15:50 +00001794template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001795void
Howard Hinnant99968442011-11-29 18:15:50 +00001796__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001797{
Howard Hinnant99968442011-11-29 18:15:50 +00001798 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001799}
1800
Howard Hinnant99968442011-11-29 18:15:50 +00001801template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001802void
Howard Hinnant99968442011-11-29 18:15:50 +00001803__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001804{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001805 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1806 typedef allocator_traits<_Ap> _ATraits;
1807 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnant99968442011-11-29 18:15:50 +00001808 _Ap __a(__f_.second());
1809 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001810 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant54da3382010-08-30 18:46:21 +00001811}
1812
Howard Hinnant99968442011-11-29 18:15:50 +00001813template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1814_Rp
1815__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001816{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001817 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001818}
1819
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001820template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001821
Howard Hinnant99968442011-11-29 18:15:50 +00001822template<class _Rp, class ..._ArgTypes>
1823class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001824{
Howard Hinnant99968442011-11-29 18:15:50 +00001825 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant78f0de22013-01-21 17:26:55 +00001826 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001827 __base* __f_;
1828
1829public:
Howard Hinnant99968442011-11-29 18:15:50 +00001830 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001831
1832 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001833 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001834 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001835 template<class _Fp>
1836 __packaged_task_function(_Fp&& __f);
1837 template<class _Fp, class _Alloc>
1838 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001839
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001840 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1841 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001842
1843 __packaged_task_function(const __packaged_task_function&) = delete;
1844 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1845
1846 ~__packaged_task_function();
1847
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001848 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001849
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00001850 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001851 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001852};
1853
Howard Hinnant99968442011-11-29 18:15:50 +00001854template<class _Rp, class ..._ArgTypes>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001855__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001856{
1857 if (__f.__f_ == nullptr)
1858 __f_ = nullptr;
1859 else if (__f.__f_ == (__base*)&__f.__buf_)
1860 {
1861 __f_ = (__base*)&__buf_;
1862 __f.__f_->__move_to(__f_);
1863 }
1864 else
1865 {
1866 __f_ = __f.__f_;
1867 __f.__f_ = nullptr;
1868 }
1869}
1870
Howard Hinnant99968442011-11-29 18:15:50 +00001871template<class _Rp, class ..._ArgTypes>
1872template <class _Fp>
1873__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001874 : __f_(nullptr)
1875{
Marshall Clowf1264e72014-04-07 13:32:26 +00001876 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnant99968442011-11-29 18:15:50 +00001877 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001878 if (sizeof(_FF) <= sizeof(__buf_))
1879 {
1880 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001881 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001882 }
1883 else
1884 {
Howard Hinnant99968442011-11-29 18:15:50 +00001885 typedef allocator<_FF> _Ap;
1886 _Ap __a;
1887 typedef __allocator_destructor<_Ap> _Dp;
1888 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1889 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001890 __f_ = __hold.release();
1891 }
1892}
1893
Howard Hinnant99968442011-11-29 18:15:50 +00001894template<class _Rp, class ..._ArgTypes>
1895template <class _Fp, class _Alloc>
1896__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1897 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001898 : __f_(nullptr)
1899{
Marshall Clowf1264e72014-04-07 13:32:26 +00001900 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnant99968442011-11-29 18:15:50 +00001901 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001902 if (sizeof(_FF) <= sizeof(__buf_))
1903 {
1904 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001905 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001906 }
1907 else
1908 {
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001909 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +00001910 _Ap __a(__a0);
1911 typedef __allocator_destructor<_Ap> _Dp;
1912 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001913 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1914 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1915 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnant54da3382010-08-30 18:46:21 +00001916 }
1917}
1918
Howard Hinnant99968442011-11-29 18:15:50 +00001919template<class _Rp, class ..._ArgTypes>
1920__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001921__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001922{
1923 if (__f_ == (__base*)&__buf_)
1924 __f_->destroy();
1925 else if (__f_)
1926 __f_->destroy_deallocate();
1927 __f_ = nullptr;
1928 if (__f.__f_ == nullptr)
1929 __f_ = nullptr;
1930 else if (__f.__f_ == (__base*)&__f.__buf_)
1931 {
1932 __f_ = (__base*)&__buf_;
1933 __f.__f_->__move_to(__f_);
1934 }
1935 else
1936 {
1937 __f_ = __f.__f_;
1938 __f.__f_ = nullptr;
1939 }
Argyrios Kyrtzidis1dc6f7a2012-10-13 02:03:45 +00001940 return *this;
Howard Hinnant54da3382010-08-30 18:46:21 +00001941}
1942
Howard Hinnant99968442011-11-29 18:15:50 +00001943template<class _Rp, class ..._ArgTypes>
1944__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001945{
1946 if (__f_ == (__base*)&__buf_)
1947 __f_->destroy();
1948 else if (__f_)
1949 __f_->destroy_deallocate();
1950}
1951
Howard Hinnant99968442011-11-29 18:15:50 +00001952template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001953void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001954__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001955{
1956 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1957 {
1958 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1959 __base* __t = (__base*)&__tempbuf;
1960 __f_->__move_to(__t);
1961 __f_->destroy();
1962 __f_ = nullptr;
1963 __f.__f_->__move_to((__base*)&__buf_);
1964 __f.__f_->destroy();
1965 __f.__f_ = nullptr;
1966 __f_ = (__base*)&__buf_;
1967 __t->__move_to((__base*)&__f.__buf_);
1968 __t->destroy();
1969 __f.__f_ = (__base*)&__f.__buf_;
1970 }
1971 else if (__f_ == (__base*)&__buf_)
1972 {
1973 __f_->__move_to((__base*)&__f.__buf_);
1974 __f_->destroy();
1975 __f_ = __f.__f_;
1976 __f.__f_ = (__base*)&__f.__buf_;
1977 }
1978 else if (__f.__f_ == (__base*)&__f.__buf_)
1979 {
1980 __f.__f_->__move_to((__base*)&__buf_);
1981 __f.__f_->destroy();
1982 __f.__f_ = __f_;
1983 __f_ = (__base*)&__buf_;
1984 }
1985 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001986 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001987}
1988
Howard Hinnant99968442011-11-29 18:15:50 +00001989template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00001990inline
Howard Hinnant99968442011-11-29 18:15:50 +00001991_Rp
1992__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00001993{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001994 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001995}
1996
Howard Hinnant99968442011-11-29 18:15:50 +00001997template<class _Rp, class ..._ArgTypes>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001998class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001999{
2000public:
Eric Fiselier68db6cd2016-06-01 21:05:53 +00002001 typedef _Rp result_type; // extension
Howard Hinnant54da3382010-08-30 18:46:21 +00002002
2003private:
2004 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2005 promise<result_type> __p_;
2006
2007public:
2008 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002009 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002010 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002011 template <class _Fp,
2012 class = typename enable_if
2013 <
2014 !is_same<
2015 typename decay<_Fp>::type,
2016 packaged_task
2017 >::value
2018 >::type
2019 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002020 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002021 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002022 template <class _Fp, class _Allocator,
2023 class = typename enable_if
2024 <
2025 !is_same<
2026 typename decay<_Fp>::type,
2027 packaged_task
2028 >::value
2029 >::type
2030 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002031 _LIBCPP_INLINE_VISIBILITY
Marshall Clow07546f32015-06-30 14:16:49 +00002032 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnant99968442011-11-29 18:15:50 +00002033 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002034 __p_(allocator_arg, __a) {}
2035 // ~packaged_task() = default;
2036
2037 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002038 packaged_task(const packaged_task&) = delete;
2039 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002040
2041 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002042 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002043 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002044 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002045 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002046 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002047 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002048 __f_ = _VSTD::move(__other.__f_);
2049 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002050 return *this;
2051 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002052 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002053 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002054 {
2055 __f_.swap(__other.__f_);
2056 __p_.swap(__other.__p_);
2057 }
2058
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002060 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002061
2062 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002063 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002064 future<result_type> get_future() {return __p_.get_future();}
2065
2066 // execution
2067 void operator()(_ArgTypes... __args);
2068 void make_ready_at_thread_exit(_ArgTypes... __args);
2069
2070 void reset();
2071};
2072
Howard Hinnant99968442011-11-29 18:15:50 +00002073template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002074void
Howard Hinnant99968442011-11-29 18:15:50 +00002075packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002076{
Howard Hinnant54da3382010-08-30 18:46:21 +00002077 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002078 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002079 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002080 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002081#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002082 try
2083 {
2084#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002085 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002086#ifndef _LIBCPP_NO_EXCEPTIONS
2087 }
2088 catch (...)
2089 {
2090 __p_.set_exception(current_exception());
2091 }
2092#endif // _LIBCPP_NO_EXCEPTIONS
2093}
2094
Howard Hinnant99968442011-11-29 18:15:50 +00002095template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002096void
Howard Hinnant99968442011-11-29 18:15:50 +00002097packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002098{
Howard Hinnant54da3382010-08-30 18:46:21 +00002099 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002100 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002101 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002102 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002103#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002104 try
2105 {
2106#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002107 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002108#ifndef _LIBCPP_NO_EXCEPTIONS
2109 }
2110 catch (...)
2111 {
2112 __p_.set_exception_at_thread_exit(current_exception());
2113 }
2114#endif // _LIBCPP_NO_EXCEPTIONS
2115}
2116
Howard Hinnant99968442011-11-29 18:15:50 +00002117template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002118void
Howard Hinnant99968442011-11-29 18:15:50 +00002119packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002120{
Howard Hinnant7de47902010-11-30 20:23:32 +00002121 if (!valid())
Eric Fiselier423ca202015-10-02 21:25:15 +00002122 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002123 __p_ = promise<result_type>();
2124}
2125
2126template<class ..._ArgTypes>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002127class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002128{
2129public:
Eric Fiselier68db6cd2016-06-01 21:05:53 +00002130 typedef void result_type; // extension
Howard Hinnant54da3382010-08-30 18:46:21 +00002131
2132private:
2133 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2134 promise<result_type> __p_;
2135
2136public:
2137 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002138 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002139 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002140 template <class _Fp,
2141 class = typename enable_if
2142 <
2143 !is_same<
2144 typename decay<_Fp>::type,
2145 packaged_task
2146 >::value
2147 >::type
2148 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002149 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002150 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002151 template <class _Fp, class _Allocator,
2152 class = typename enable_if
2153 <
2154 !is_same<
2155 typename decay<_Fp>::type,
2156 packaged_task
2157 >::value
2158 >::type
2159 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002160 _LIBCPP_INLINE_VISIBILITY
Marshall Clow5706c372015-06-30 18:28:35 +00002161 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnant99968442011-11-29 18:15:50 +00002162 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002163 __p_(allocator_arg, __a) {}
2164 // ~packaged_task() = default;
2165
2166 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002167 packaged_task(const packaged_task&) = delete;
2168 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002169
2170 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002171 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002172 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002173 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002174 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002175 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002176 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002177 __f_ = _VSTD::move(__other.__f_);
2178 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002179 return *this;
2180 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002181 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002182 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002183 {
2184 __f_.swap(__other.__f_);
2185 __p_.swap(__other.__p_);
2186 }
2187
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002188 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002189 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002190
2191 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002192 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002193 future<result_type> get_future() {return __p_.get_future();}
2194
2195 // execution
2196 void operator()(_ArgTypes... __args);
2197 void make_ready_at_thread_exit(_ArgTypes... __args);
2198
2199 void reset();
2200};
2201
2202template<class ..._ArgTypes>
2203void
2204packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2205{
Howard Hinnant54da3382010-08-30 18:46:21 +00002206 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002207 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002208 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002209 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002210#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002211 try
2212 {
2213#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002214 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002215 __p_.set_value();
2216#ifndef _LIBCPP_NO_EXCEPTIONS
2217 }
2218 catch (...)
2219 {
2220 __p_.set_exception(current_exception());
2221 }
2222#endif // _LIBCPP_NO_EXCEPTIONS
2223}
2224
2225template<class ..._ArgTypes>
2226void
2227packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2228{
Howard Hinnant54da3382010-08-30 18:46:21 +00002229 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002230 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002231 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002232 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002233#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002234 try
2235 {
2236#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002237 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002238 __p_.set_value_at_thread_exit();
2239#ifndef _LIBCPP_NO_EXCEPTIONS
2240 }
2241 catch (...)
2242 {
2243 __p_.set_exception_at_thread_exit(current_exception());
2244 }
2245#endif // _LIBCPP_NO_EXCEPTIONS
2246}
2247
2248template<class ..._ArgTypes>
2249void
2250packaged_task<void(_ArgTypes...)>::reset()
2251{
Howard Hinnant7de47902010-11-30 20:23:32 +00002252 if (!valid())
Eric Fiselier423ca202015-10-02 21:25:15 +00002253 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002254 __p_ = promise<result_type>();
2255}
2256
2257template <class _Callable>
2258inline _LIBCPP_INLINE_VISIBILITY
2259void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002260swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002261{
2262 __x.swap(__y);
2263}
2264
2265template <class _Callable, class _Alloc>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002266struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002267 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002268
Howard Hinnant99968442011-11-29 18:15:50 +00002269template <class _Rp, class _Fp>
2270future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002271#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002272__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002273#else
Howard Hinnant99968442011-11-29 18:15:50 +00002274__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002275#endif
2276{
Howard Hinnant99968442011-11-29 18:15:50 +00002277 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2278 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2279 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002280}
2281
Howard Hinnant99968442011-11-29 18:15:50 +00002282template <class _Rp, class _Fp>
2283future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002284#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002285__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002286#else
Howard Hinnant99968442011-11-29 18:15:50 +00002287__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002288#endif
2289{
Howard Hinnant99968442011-11-29 18:15:50 +00002290 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2291 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2292 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2293 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002294}
2295
Howard Hinnant99968442011-11-29 18:15:50 +00002296template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002297class __async_func
2298{
Howard Hinnant99968442011-11-29 18:15:50 +00002299 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002300
2301public:
Howard Hinnant99968442011-11-29 18:15:50 +00002302 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002303
2304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002305 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002306 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002307
2308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002309 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002310
Howard Hinnant99968442011-11-29 18:15:50 +00002311 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002312 {
2313 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2314 return __execute(_Index());
2315 }
2316private:
2317 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002318 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002319 __execute(__tuple_indices<_Indices...>)
2320 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002321 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002322 }
2323};
2324
Marshall Clow3b3108e2013-11-03 22:06:53 +00002325inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clowad2a6002013-11-03 15:43:35 +00002326{ return (int(__policy) & int(__value)) != 0; }
2327
Howard Hinnant99968442011-11-29 18:15:50 +00002328template <class _Fp, class... _Args>
2329future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2330async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002331{
Howard Hinnant99968442011-11-29 18:15:50 +00002332 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2333 typedef typename _BF::_Rp _Rp;
Marshall Clowad2a6002013-11-03 15:43:35 +00002334
2335#ifndef _LIBCPP_NO_EXCEPTIONS
2336 try
2337 {
2338#endif
2339 if (__does_policy_contain(__policy, launch::async))
2340 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002341 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clowad2a6002013-11-03 15:43:35 +00002342#ifndef _LIBCPP_NO_EXCEPTIONS
2343 }
2344 catch ( ... ) { if (__policy == launch::async) throw ; }
2345#endif
2346
2347 if (__does_policy_contain(__policy, launch::deferred))
2348 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002349 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clowad2a6002013-11-03 15:43:35 +00002350 return future<_Rp>{};
Howard Hinnant54da3382010-08-30 18:46:21 +00002351}
2352
Howard Hinnant99968442011-11-29 18:15:50 +00002353template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002354inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002355future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2356async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002357{
Howard Hinnant99968442011-11-29 18:15:50 +00002358 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002359 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002360}
2361
2362#endif // _LIBCPP_HAS_NO_VARIADICS
2363
Howard Hinnante6e4d012010-09-03 21:46:37 +00002364// shared_future
2365
Howard Hinnant99968442011-11-29 18:15:50 +00002366template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002367class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002368{
Howard Hinnant99968442011-11-29 18:15:50 +00002369 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002370
2371public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002372 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002373 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002375 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2376 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002377#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002378 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002379 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002380 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002381 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002382 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002383 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002384#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002385 ~shared_future();
2386 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002389 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002390 {
2391 shared_future(std::move(__rhs)).swap(*this);
2392 return *this;
2393 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002394#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002395
2396 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002397 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002398 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002399
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002401 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002402
2403 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002405 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002406
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002408 void wait() const {__state_->wait();}
2409 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002411 future_status
2412 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2413 {return __state_->wait_for(__rel_time);}
2414 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002415 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002416 future_status
2417 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2418 {return __state_->wait_until(__abs_time);}
2419};
2420
Howard Hinnant99968442011-11-29 18:15:50 +00002421template <class _Rp>
2422shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002423{
2424 if (__state_)
2425 __state_->__release_shared();
2426}
2427
Howard Hinnant99968442011-11-29 18:15:50 +00002428template <class _Rp>
2429shared_future<_Rp>&
2430shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002431{
2432 if (__rhs.__state_)
2433 __rhs.__state_->__add_shared();
2434 if (__state_)
2435 __state_->__release_shared();
2436 __state_ = __rhs.__state_;
2437 return *this;
2438}
2439
Howard Hinnant99968442011-11-29 18:15:50 +00002440template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002441class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002442{
Howard Hinnant99968442011-11-29 18:15:50 +00002443 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002444
2445public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002447 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002449 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2450 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002451#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002453 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002454 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002456 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002457 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002458#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002459 ~shared_future();
2460 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002461#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002462 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002463 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002464 {
2465 shared_future(std::move(__rhs)).swap(*this);
2466 return *this;
2467 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002468#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002469
2470 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002472 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002473
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002475 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002476
2477 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002479 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002480
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002482 void wait() const {__state_->wait();}
2483 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002485 future_status
2486 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2487 {return __state_->wait_for(__rel_time);}
2488 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002489 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002490 future_status
2491 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2492 {return __state_->wait_until(__abs_time);}
2493};
2494
Howard Hinnant99968442011-11-29 18:15:50 +00002495template <class _Rp>
2496shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002497{
2498 if (__state_)
2499 __state_->__release_shared();
2500}
2501
Howard Hinnant99968442011-11-29 18:15:50 +00002502template <class _Rp>
2503shared_future<_Rp&>&
2504shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002505{
2506 if (__rhs.__state_)
2507 __rhs.__state_->__add_shared();
2508 if (__state_)
2509 __state_->__release_shared();
2510 __state_ = __rhs.__state_;
2511 return *this;
2512}
2513
2514template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00002515class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002516{
2517 __assoc_sub_state* __state_;
2518
2519public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002520 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002521 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002522 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002523 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2524 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002525#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002527 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002528 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002529 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002530 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002531 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002532#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002533 ~shared_future();
2534 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002535#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002537 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002538 {
2539 shared_future(std::move(__rhs)).swap(*this);
2540 return *this;
2541 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002542#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002543
2544 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002545 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002546 void get() const {__state_->copy();}
2547
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002549 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002550
2551 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002553 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002554
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002556 void wait() const {__state_->wait();}
2557 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002559 future_status
2560 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2561 {return __state_->wait_for(__rel_time);}
2562 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002564 future_status
2565 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2566 {return __state_->wait_until(__abs_time);}
2567};
2568
Howard Hinnant99968442011-11-29 18:15:50 +00002569template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002570inline _LIBCPP_INLINE_VISIBILITY
2571void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002572swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002573{
2574 __x.swap(__y);
2575}
2576
Howard Hinnant99968442011-11-29 18:15:50 +00002577template <class _Rp>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00002578inline
Howard Hinnant99968442011-11-29 18:15:50 +00002579shared_future<_Rp>
2580future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002581{
Howard Hinnant99968442011-11-29 18:15:50 +00002582 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002583}
2584
Howard Hinnant99968442011-11-29 18:15:50 +00002585template <class _Rp>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00002586inline
Howard Hinnant99968442011-11-29 18:15:50 +00002587shared_future<_Rp&>
2588future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002589{
Howard Hinnant99968442011-11-29 18:15:50 +00002590 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002591}
2592
Howard Hinnanta4451512010-12-02 16:45:21 +00002593#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2594
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +00002595inline
Howard Hinnant7de47902010-11-30 20:23:32 +00002596shared_future<void>
2597future<void>::share()
2598{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002599 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002600}
2601
Howard Hinnanta4451512010-12-02 16:45:21 +00002602#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2603
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002604_LIBCPP_END_NAMESPACE_STD
2605
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +00002606#endif // !_LIBCPP_HAS_NO_THREADS
2607
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002608#endif // _LIBCPP_FUTURE