blob: 5b5afe6e27719bb21ed29e784c0e286cec2eacfb [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:
325 typedef R result_type;
326
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
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000515class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant47499b12010-08-27 20:10:19 +0000516 : public __shared_count
517{
518protected:
519 exception_ptr __exception_;
520 mutable mutex __mut_;
521 mutable condition_variable __cv_;
522 unsigned __state_;
523
Howard Hinnant1694d232011-05-28 14:41:13 +0000524 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000525 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000526public:
527 enum
528 {
529 __constructed = 1,
530 __future_attached = 2,
531 ready = 4,
532 deferred = 8
533 };
534
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000536 __assoc_sub_state() : __state_(0) {}
537
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000539 bool __has_value() const
540 {return (__state_ & __constructed) || (__exception_ != nullptr);}
541
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1b031c92013-01-14 20:01:24 +0000543 void __set_future_attached()
544 {
545 lock_guard<mutex> __lk(__mut_);
546 __state_ |= __future_attached;
547 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Marshall Clow9de3d4c2013-10-13 01:02:45 +0000549 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant47499b12010-08-27 20:10:19 +0000550
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000552 void __set_deferred() {__state_ |= deferred;}
553
Howard Hinnant47499b12010-08-27 20:10:19 +0000554 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000555 _LIBCPP_INLINE_VISIBILITY
Marshall Clow9de3d4c2013-10-13 01:02:45 +0000556 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant47499b12010-08-27 20:10:19 +0000557
558 void set_value();
559 void set_value_at_thread_exit();
560
561 void set_exception(exception_ptr __p);
562 void set_exception_at_thread_exit(exception_ptr __p);
563
564 void copy();
565
Howard Hinnant54da3382010-08-30 18:46:21 +0000566 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000567 template <class _Rep, class _Period>
568 future_status
569 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
570 template <class _Clock, class _Duration>
571 future_status
572 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000573
574 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000575};
576
Howard Hinnantf39daa82010-08-28 21:01:06 +0000577template <class _Clock, class _Duration>
578future_status
579__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
580{
581 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000582 if (__state_ & deferred)
583 return future_status::deferred;
584 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000585 __cv_.wait_until(__lk, __abs_time);
586 if (__state_ & ready)
587 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000588 return future_status::timeout;
589}
590
591template <class _Rep, class _Period>
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700592inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000593future_status
594__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
595{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000596 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000597}
598
Howard Hinnant99968442011-11-29 18:15:50 +0000599template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000600class __assoc_state
601 : public __assoc_sub_state
602{
603 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000604 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000605protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000606 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000607
Howard Hinnant1694d232011-05-28 14:41:13 +0000608 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000609public:
610
611 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000612#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000613 void set_value(_Arg&& __arg);
614#else
615 void set_value(_Arg& __arg);
616#endif
617
618 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000619#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000620 void set_value_at_thread_exit(_Arg&& __arg);
621#else
622 void set_value_at_thread_exit(_Arg& __arg);
623#endif
624
Howard Hinnant99968442011-11-29 18:15:50 +0000625 _Rp move();
626 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000627};
628
Howard Hinnant99968442011-11-29 18:15:50 +0000629template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000630void
Howard Hinnant99968442011-11-29 18:15:50 +0000631__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000632{
633 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000634 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000635 delete this;
636}
637
Howard Hinnant99968442011-11-29 18:15:50 +0000638template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000639template <class _Arg>
640void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000641#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000642__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000643#else
Howard Hinnant99968442011-11-29 18:15:50 +0000644__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000645#endif
646{
647 unique_lock<mutex> __lk(this->__mut_);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700648#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000649 if (this->__has_value())
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700650 throw future_error(make_error_code(future_errc::promise_already_satisfied));
651#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000652 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000653 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant47499b12010-08-27 20:10:19 +0000654 __cv_.notify_all();
655}
656
Howard Hinnant99968442011-11-29 18:15:50 +0000657template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000658template <class _Arg>
659void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000660#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000661__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000662#else
Howard Hinnant99968442011-11-29 18:15:50 +0000663__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000664#endif
665{
666 unique_lock<mutex> __lk(this->__mut_);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700667#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000668 if (this->__has_value())
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700669 throw future_error(make_error_code(future_errc::promise_already_satisfied));
670#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000671 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000672 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000673 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000674}
675
Howard Hinnant99968442011-11-29 18:15:50 +0000676template <class _Rp>
677_Rp
678__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000679{
680 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000681 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000682 if (this->__exception_ != nullptr)
683 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000684 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000685}
686
Howard Hinnant99968442011-11-29 18:15:50 +0000687template <class _Rp>
688typename add_lvalue_reference<_Rp>::type
689__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000690{
691 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000692 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000693 if (this->__exception_ != nullptr)
694 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000695 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000696}
697
Howard Hinnant99968442011-11-29 18:15:50 +0000698template <class _Rp>
699class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000700 : public __assoc_sub_state
701{
702 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000703 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000704protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000705 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000706
Howard Hinnant1694d232011-05-28 14:41:13 +0000707 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000708public:
709
Howard Hinnant99968442011-11-29 18:15:50 +0000710 void set_value(_Rp& __arg);
711 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000712
Howard Hinnant99968442011-11-29 18:15:50 +0000713 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000714};
715
Howard Hinnant99968442011-11-29 18:15:50 +0000716template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000717void
Howard Hinnant99968442011-11-29 18:15:50 +0000718__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000719{
720 delete this;
721}
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&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000726{
727 unique_lock<mutex> __lk(this->__mut_);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700728#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000729 if (this->__has_value())
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700730 throw future_error(make_error_code(future_errc::promise_already_satisfied));
731#endif
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000732 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000733 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000734 __cv_.notify_all();
735}
736
Howard Hinnant99968442011-11-29 18:15:50 +0000737template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000738void
Howard Hinnant99968442011-11-29 18:15:50 +0000739__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000740{
741 unique_lock<mutex> __lk(this->__mut_);
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700742#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000743 if (this->__has_value())
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700744 throw future_error(make_error_code(future_errc::promise_already_satisfied));
745#endif
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000746 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000747 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000748 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000749}
750
Howard Hinnant99968442011-11-29 18:15:50 +0000751template <class _Rp>
752_Rp&
753__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000754{
755 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000756 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000757 if (this->__exception_ != nullptr)
758 rethrow_exception(this->__exception_);
759 return *__value_;
760}
761
Howard Hinnant99968442011-11-29 18:15:50 +0000762template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000763class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000764 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000765{
Howard Hinnant99968442011-11-29 18:15:50 +0000766 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000767 _Alloc __alloc_;
768
Howard Hinnant1694d232011-05-28 14:41:13 +0000769 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000770public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000771 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000772 explicit __assoc_state_alloc(const _Alloc& __a)
773 : __alloc_(__a) {}
774};
775
Howard Hinnant99968442011-11-29 18:15:50 +0000776template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000777void
Howard Hinnant99968442011-11-29 18:15:50 +0000778__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000779{
780 if (this->__state_ & base::__constructed)
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000781 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselier8492cd82015-02-05 23:01:40 +0000782 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
783 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000784 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000785 _Al __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000786 this->~__assoc_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000787 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant47499b12010-08-27 20:10:19 +0000788}
789
Howard Hinnant99968442011-11-29 18:15:50 +0000790template <class _Rp, class _Alloc>
791class __assoc_state_alloc<_Rp&, _Alloc>
792 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000793{
Howard Hinnant99968442011-11-29 18:15:50 +0000794 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000795 _Alloc __alloc_;
796
Howard Hinnant1694d232011-05-28 14:41:13 +0000797 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000798public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000799 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000800 explicit __assoc_state_alloc(const _Alloc& __a)
801 : __alloc_(__a) {}
802};
803
Howard Hinnant99968442011-11-29 18:15:50 +0000804template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000805void
Howard Hinnant99968442011-11-29 18:15:50 +0000806__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000807{
Eric Fiselier8492cd82015-02-05 23:01:40 +0000808 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
809 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000810 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000811 _Al __a(__alloc_);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000812 this->~__assoc_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000813 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000814}
815
Howard Hinnant47499b12010-08-27 20:10:19 +0000816template <class _Alloc>
817class __assoc_sub_state_alloc
818 : public __assoc_sub_state
819{
820 typedef __assoc_sub_state base;
821 _Alloc __alloc_;
822
Howard Hinnant1694d232011-05-28 14:41:13 +0000823 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000824public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000825 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000826 explicit __assoc_sub_state_alloc(const _Alloc& __a)
827 : __alloc_(__a) {}
828};
829
830template <class _Alloc>
831void
Howard Hinnant1694d232011-05-28 14:41:13 +0000832__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000833{
Eric Fiselier8492cd82015-02-05 23:01:40 +0000834 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
835 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000836 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000837 _Al __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000838 this->~__assoc_sub_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000839 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant47499b12010-08-27 20:10:19 +0000840}
841
Howard Hinnant99968442011-11-29 18:15:50 +0000842template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000843class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000844 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000845{
Howard Hinnant99968442011-11-29 18:15:50 +0000846 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000847
Howard Hinnant99968442011-11-29 18:15:50 +0000848 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000849
850public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000851#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000852 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000853#endif
854
855 virtual void __execute();
856};
857
Howard Hinnant73d21a42010-09-04 23:28:19 +0000858#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000859
Howard Hinnant99968442011-11-29 18:15:50 +0000860template <class _Rp, class _Fp>
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700861inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000862__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
863 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000864{
865 this->__set_deferred();
866}
867
Howard Hinnant73d21a42010-09-04 23:28:19 +0000868#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000869
Howard Hinnant99968442011-11-29 18:15:50 +0000870template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000871void
Howard Hinnant99968442011-11-29 18:15:50 +0000872__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000873{
874#ifndef _LIBCPP_NO_EXCEPTIONS
875 try
876 {
877#endif // _LIBCPP_NO_EXCEPTIONS
878 this->set_value(__func_());
879#ifndef _LIBCPP_NO_EXCEPTIONS
880 }
881 catch (...)
882 {
883 this->set_exception(current_exception());
884 }
885#endif // _LIBCPP_NO_EXCEPTIONS
886}
887
Howard Hinnant99968442011-11-29 18:15:50 +0000888template <class _Fp>
889class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000890 : public __assoc_sub_state
891{
892 typedef __assoc_sub_state base;
893
Howard Hinnant99968442011-11-29 18:15:50 +0000894 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000895
896public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000897#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000898 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000899#endif
900
901 virtual void __execute();
902};
903
Howard Hinnant73d21a42010-09-04 23:28:19 +0000904#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000905
Howard Hinnant99968442011-11-29 18:15:50 +0000906template <class _Fp>
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700907inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000908__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
909 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000910{
911 this->__set_deferred();
912}
913
Howard Hinnant73d21a42010-09-04 23:28:19 +0000914#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000915
Howard Hinnant99968442011-11-29 18:15:50 +0000916template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000917void
Howard Hinnant99968442011-11-29 18:15:50 +0000918__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000919{
920#ifndef _LIBCPP_NO_EXCEPTIONS
921 try
922 {
923#endif // _LIBCPP_NO_EXCEPTIONS
924 __func_();
925 this->set_value();
926#ifndef _LIBCPP_NO_EXCEPTIONS
927 }
928 catch (...)
929 {
930 this->set_exception(current_exception());
931 }
932#endif // _LIBCPP_NO_EXCEPTIONS
933}
934
Howard Hinnant99968442011-11-29 18:15:50 +0000935template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000936class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000937 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000938{
Howard Hinnant99968442011-11-29 18:15:50 +0000939 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000940
Howard Hinnant99968442011-11-29 18:15:50 +0000941 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000942
Howard Hinnant1694d232011-05-28 14:41:13 +0000943 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000944public:
945#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000946 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000947#endif
948
949 virtual void __execute();
950};
951
952#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
953
Howard Hinnant99968442011-11-29 18:15:50 +0000954template <class _Rp, class _Fp>
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700955inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000956__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
957 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000958{
959}
960
961#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
962
Howard Hinnant99968442011-11-29 18:15:50 +0000963template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000964void
Howard Hinnant99968442011-11-29 18:15:50 +0000965__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000966{
967#ifndef _LIBCPP_NO_EXCEPTIONS
968 try
969 {
970#endif // _LIBCPP_NO_EXCEPTIONS
971 this->set_value(__func_());
972#ifndef _LIBCPP_NO_EXCEPTIONS
973 }
974 catch (...)
975 {
976 this->set_exception(current_exception());
977 }
978#endif // _LIBCPP_NO_EXCEPTIONS
979}
980
Howard Hinnant99968442011-11-29 18:15:50 +0000981template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000982void
Howard Hinnant99968442011-11-29 18:15:50 +0000983__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000984{
985 this->wait();
986 base::__on_zero_shared();
987}
988
Howard Hinnant99968442011-11-29 18:15:50 +0000989template <class _Fp>
990class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000991 : public __assoc_sub_state
992{
993 typedef __assoc_sub_state base;
994
Howard Hinnant99968442011-11-29 18:15:50 +0000995 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000996
Howard Hinnant1694d232011-05-28 14:41:13 +0000997 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000998public:
999#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001000 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001001#endif
1002
1003 virtual void __execute();
1004};
1005
1006#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1007
Howard Hinnant99968442011-11-29 18:15:50 +00001008template <class _Fp>
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001009inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001010__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1011 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +00001012{
1013}
1014
1015#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1016
Howard Hinnant99968442011-11-29 18:15:50 +00001017template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001018void
Howard Hinnant99968442011-11-29 18:15:50 +00001019__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +00001020{
1021#ifndef _LIBCPP_NO_EXCEPTIONS
1022 try
1023 {
1024#endif // _LIBCPP_NO_EXCEPTIONS
1025 __func_();
1026 this->set_value();
1027#ifndef _LIBCPP_NO_EXCEPTIONS
1028 }
1029 catch (...)
1030 {
1031 this->set_exception(current_exception());
1032 }
1033#endif // _LIBCPP_NO_EXCEPTIONS
1034}
1035
Howard Hinnant99968442011-11-29 18:15:50 +00001036template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001037void
Howard Hinnant99968442011-11-29 18:15:50 +00001038__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +00001039{
1040 this->wait();
1041 base::__on_zero_shared();
1042}
1043
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001044template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1045template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +00001046
1047// future
1048
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001049template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001050
Howard Hinnant99968442011-11-29 18:15:50 +00001051template <class _Rp, class _Fp>
1052future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001053#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001054__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001055#else
Howard Hinnant99968442011-11-29 18:15:50 +00001056__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001057#endif
1058
Howard Hinnant99968442011-11-29 18:15:50 +00001059template <class _Rp, class _Fp>
1060future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001061#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001062__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001063#else
Howard Hinnant99968442011-11-29 18:15:50 +00001064__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001065#endif
1066
Howard Hinnant99968442011-11-29 18:15:50 +00001067template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001068class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant47499b12010-08-27 20:10:19 +00001069{
Howard Hinnant99968442011-11-29 18:15:50 +00001070 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001071
Howard Hinnant99968442011-11-29 18:15:50 +00001072 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001073
1074 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001075 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001076
Howard Hinnant73d21a42010-09-04 23:28:19 +00001077#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001078 template <class _R1, class _Fp>
1079 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1080 template <class _R1, class _Fp>
1081 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001082#else
Howard Hinnant99968442011-11-29 18:15:50 +00001083 template <class _R1, class _Fp>
1084 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1085 template <class _R1, class _Fp>
1086 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001087#endif
1088
Howard Hinnant47499b12010-08-27 20:10:19 +00001089public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001090 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001091 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001092#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001093 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001094 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001095 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1096 future(const future&) = delete;
1097 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001098 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001099 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001100 {
1101 future(std::move(__rhs)).swap(*this);
1102 return *this;
1103 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001104#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001105private:
1106 future(const future&);
1107 future& operator=(const future&);
1108public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001109#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001110 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001111 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001112
1113 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001114 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001115
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001116 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001117 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001118
1119 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001120 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001121 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001122
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001123 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001124 void wait() const {__state_->wait();}
1125 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001126 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001127 future_status
1128 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1129 {return __state_->wait_for(__rel_time);}
1130 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001131 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001132 future_status
1133 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1134 {return __state_->wait_until(__abs_time);}
1135};
1136
Howard Hinnant99968442011-11-29 18:15:50 +00001137template <class _Rp>
1138future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001139 : __state_(__state)
1140{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001141#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001142 if (__state_->__has_future_attached())
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001143 throw future_error(make_error_code(future_errc::future_already_retrieved));
1144#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001145 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001146 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001147}
1148
Howard Hinnant54da3382010-08-30 18:46:21 +00001149struct __release_shared_count
1150{
1151 void operator()(__shared_count* p) {p->__release_shared();}
1152};
1153
Howard Hinnant99968442011-11-29 18:15:50 +00001154template <class _Rp>
1155future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001156{
1157 if (__state_)
1158 __state_->__release_shared();
1159}
1160
Howard Hinnant99968442011-11-29 18:15:50 +00001161template <class _Rp>
1162_Rp
1163future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001164{
Howard Hinnant54da3382010-08-30 18:46:21 +00001165 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001166 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001167 __state_ = nullptr;
1168 return __s->move();
1169}
1170
Howard Hinnant99968442011-11-29 18:15:50 +00001171template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001172class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001173{
Howard Hinnant99968442011-11-29 18:15:50 +00001174 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001175
Howard Hinnant99968442011-11-29 18:15:50 +00001176 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001177
1178 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001179 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001180
Howard Hinnant73d21a42010-09-04 23:28:19 +00001181#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001182 template <class _R1, class _Fp>
1183 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1184 template <class _R1, class _Fp>
1185 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001186#else
Howard Hinnant99968442011-11-29 18:15:50 +00001187 template <class _R1, class _Fp>
1188 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1189 template <class _R1, class _Fp>
1190 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001191#endif
1192
Howard Hinnant47499b12010-08-27 20:10:19 +00001193public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001194 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001195 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001196#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001198 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001199 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1200 future(const future&) = delete;
1201 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001202 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001203 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001204 {
1205 future(std::move(__rhs)).swap(*this);
1206 return *this;
1207 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001208#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001209private:
1210 future(const future&);
1211 future& operator=(const future&);
1212public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001213#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001214 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001215 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001216
1217 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001218 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001219
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001220 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001221 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001222
1223 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001224 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001225 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001226
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001227 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001228 void wait() const {__state_->wait();}
1229 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001230 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001231 future_status
1232 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1233 {return __state_->wait_for(__rel_time);}
1234 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001235 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001236 future_status
1237 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1238 {return __state_->wait_until(__abs_time);}
1239};
1240
Howard Hinnant99968442011-11-29 18:15:50 +00001241template <class _Rp>
1242future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001243 : __state_(__state)
1244{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001245#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001246 if (__state_->__has_future_attached())
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001247 throw future_error(make_error_code(future_errc::future_already_retrieved));
1248#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001249 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001250 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001251}
1252
Howard Hinnant99968442011-11-29 18:15:50 +00001253template <class _Rp>
1254future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001255{
1256 if (__state_)
1257 __state_->__release_shared();
1258}
1259
Howard Hinnant99968442011-11-29 18:15:50 +00001260template <class _Rp>
1261_Rp&
1262future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001263{
Howard Hinnant54da3382010-08-30 18:46:21 +00001264 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001265 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001266 __state_ = nullptr;
1267 return __s->copy();
1268}
1269
1270template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001271class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001272{
1273 __assoc_sub_state* __state_;
1274
1275 explicit future(__assoc_sub_state* __state);
1276
1277 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001278 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001279
Howard Hinnant73d21a42010-09-04 23:28:19 +00001280#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001281 template <class _R1, class _Fp>
1282 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1283 template <class _R1, class _Fp>
1284 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001285#else
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#endif
1291
Howard Hinnant47499b12010-08-27 20:10:19 +00001292public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001293 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001294 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001295#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001296 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001297 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001298 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1299 future(const future&) = delete;
1300 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001302 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001303 {
1304 future(std::move(__rhs)).swap(*this);
1305 return *this;
1306 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001307#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001308private:
1309 future(const future&);
1310 future& operator=(const future&);
1311public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001312#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001313 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001314 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001315
1316 // retrieving the value
1317 void get();
1318
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001320 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001321
1322 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001324 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001325
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001327 void wait() const {__state_->wait();}
1328 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001330 future_status
1331 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1332 {return __state_->wait_for(__rel_time);}
1333 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001335 future_status
1336 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1337 {return __state_->wait_until(__abs_time);}
1338};
1339
Howard Hinnant99968442011-11-29 18:15:50 +00001340template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001341inline _LIBCPP_INLINE_VISIBILITY
1342void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001343swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00001344{
1345 __x.swap(__y);
1346}
1347
Howard Hinnant47499b12010-08-27 20:10:19 +00001348// promise<R>
1349
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001350template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001351
Howard Hinnant99968442011-11-29 18:15:50 +00001352template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001353class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001354{
Howard Hinnant99968442011-11-29 18:15:50 +00001355 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001356
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001357 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001358 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001359
1360 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001361public:
1362 promise();
1363 template <class _Alloc>
1364 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001365#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001367 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001368 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1369 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001370#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001371private:
1372 promise(const promise& __rhs);
1373public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001374#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001375 ~promise();
1376
1377 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001378#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001379 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001380 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001381 {
1382 promise(std::move(__rhs)).swap(*this);
1383 return *this;
1384 }
1385 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001386#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001387private:
1388 promise& operator=(const promise& __rhs);
1389public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001390#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001392 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001393
1394 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001395 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001396
1397 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001398 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001399#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001400 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001401#endif
1402 void set_exception(exception_ptr __p);
1403
1404 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001405 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001406#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001407 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001408#endif
1409 void set_exception_at_thread_exit(exception_ptr __p);
1410};
1411
Howard Hinnant99968442011-11-29 18:15:50 +00001412template <class _Rp>
1413promise<_Rp>::promise()
1414 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001415{
1416}
1417
Howard Hinnant99968442011-11-29 18:15:50 +00001418template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001419template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001420promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001421{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001422 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1423 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001424 typedef __allocator_destructor<_A2> _D2;
1425 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001426 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1427 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1428 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001429}
1430
Howard Hinnant99968442011-11-29 18:15:50 +00001431template <class _Rp>
1432promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001433{
1434 if (__state_)
1435 {
1436 if (!__state_->__has_value() && __state_->use_count() > 1)
1437 __state_->set_exception(make_exception_ptr(
1438 future_error(make_error_code(future_errc::broken_promise))
1439 ));
1440 __state_->__release_shared();
1441 }
1442}
1443
Howard Hinnant99968442011-11-29 18:15:50 +00001444template <class _Rp>
1445future<_Rp>
1446promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001447{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001448#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001449 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001450 throw future_error(make_error_code(future_errc::no_state));
1451#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001452 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001453}
1454
Howard Hinnant99968442011-11-29 18:15:50 +00001455template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001456void
Howard Hinnant99968442011-11-29 18:15:50 +00001457promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001458{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001459#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001460 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001461 throw future_error(make_error_code(future_errc::no_state));
1462#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001463 __state_->set_value(__r);
1464}
1465
Howard Hinnant73d21a42010-09-04 23:28:19 +00001466#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001467
Howard Hinnant99968442011-11-29 18:15:50 +00001468template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001469void
Howard Hinnant99968442011-11-29 18:15:50 +00001470promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001471{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001472#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001473 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001474 throw future_error(make_error_code(future_errc::no_state));
1475#endif
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{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001485#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001486 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001487 throw future_error(make_error_code(future_errc::no_state));
1488#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001489 __state_->set_exception(__p);
1490}
1491
Howard Hinnant99968442011-11-29 18:15:50 +00001492template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001493void
Howard Hinnant99968442011-11-29 18:15:50 +00001494promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001495{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001496#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001497 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001498 throw future_error(make_error_code(future_errc::no_state));
1499#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001500 __state_->set_value_at_thread_exit(__r);
1501}
1502
Howard Hinnant73d21a42010-09-04 23:28:19 +00001503#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001504
Howard Hinnant99968442011-11-29 18:15:50 +00001505template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001506void
Howard Hinnant99968442011-11-29 18:15:50 +00001507promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001508{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001509#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001510 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001511 throw future_error(make_error_code(future_errc::no_state));
1512#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001513 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001514}
1515
Howard Hinnant73d21a42010-09-04 23:28:19 +00001516#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001517
Howard Hinnant99968442011-11-29 18:15:50 +00001518template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001519void
Howard Hinnant99968442011-11-29 18:15:50 +00001520promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001521{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001522#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001523 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001524 throw future_error(make_error_code(future_errc::no_state));
1525#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001526 __state_->set_exception_at_thread_exit(__p);
1527}
1528
1529// promise<R&>
1530
Howard Hinnant99968442011-11-29 18:15:50 +00001531template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001532class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001533{
Howard Hinnant99968442011-11-29 18:15:50 +00001534 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001535
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001537 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001538
1539 template <class> friend class packaged_task;
1540
Howard Hinnant47499b12010-08-27 20:10:19 +00001541public:
1542 promise();
1543 template <class _Allocator>
1544 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001545#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001547 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001548 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1549 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001550#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001551private:
1552 promise(const promise& __rhs);
1553public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001554#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001555 ~promise();
1556
1557 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001558#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001559 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001560 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001561 {
1562 promise(std::move(__rhs)).swap(*this);
1563 return *this;
1564 }
1565 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001566#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001567private:
1568 promise& operator=(const promise& __rhs);
1569public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001570#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001571 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001572 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001573
1574 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001575 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001576
1577 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001578 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001579 void set_exception(exception_ptr __p);
1580
1581 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001582 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001583 void set_exception_at_thread_exit(exception_ptr __p);
1584};
1585
Howard Hinnant99968442011-11-29 18:15:50 +00001586template <class _Rp>
1587promise<_Rp&>::promise()
1588 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001589{
1590}
1591
Howard Hinnant99968442011-11-29 18:15:50 +00001592template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001593template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001594promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001595{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001596 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1597 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001598 typedef __allocator_destructor<_A2> _D2;
1599 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001600 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1601 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1602 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001603}
1604
Howard Hinnant99968442011-11-29 18:15:50 +00001605template <class _Rp>
1606promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001607{
1608 if (__state_)
1609 {
1610 if (!__state_->__has_value() && __state_->use_count() > 1)
1611 __state_->set_exception(make_exception_ptr(
1612 future_error(make_error_code(future_errc::broken_promise))
1613 ));
1614 __state_->__release_shared();
1615 }
1616}
1617
Howard Hinnant99968442011-11-29 18:15:50 +00001618template <class _Rp>
1619future<_Rp&>
1620promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001621{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001622#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001623 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001624 throw future_error(make_error_code(future_errc::no_state));
1625#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001626 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001627}
1628
Howard Hinnant99968442011-11-29 18:15:50 +00001629template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001630void
Howard Hinnant99968442011-11-29 18:15:50 +00001631promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001632{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001633#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001634 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001635 throw future_error(make_error_code(future_errc::no_state));
1636#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001637 __state_->set_value(__r);
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_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001643{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001644#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001645 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001646 throw future_error(make_error_code(future_errc::no_state));
1647#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001648 __state_->set_exception(__p);
1649}
1650
Howard Hinnant99968442011-11-29 18:15:50 +00001651template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001652void
Howard Hinnant99968442011-11-29 18:15:50 +00001653promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001654{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001655#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001656 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001657 throw future_error(make_error_code(future_errc::no_state));
1658#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001659 __state_->set_value_at_thread_exit(__r);
1660}
1661
Howard Hinnant99968442011-11-29 18:15:50 +00001662template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001663void
Howard Hinnant99968442011-11-29 18:15:50 +00001664promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001665{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001666#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001667 if (__state_ == nullptr)
Dan Albert1d4a1ed2016-05-25 22:36:09 -07001668 throw future_error(make_error_code(future_errc::no_state));
1669#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001670 __state_->set_exception_at_thread_exit(__p);
1671}
1672
1673// promise<void>
1674
1675template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001676class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001677{
1678 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001679
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001680 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001681 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001682
1683 template <class> friend class packaged_task;
1684
Howard Hinnant47499b12010-08-27 20:10:19 +00001685public:
1686 promise();
1687 template <class _Allocator>
1688 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001689#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001690 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001691 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001692 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1693 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001694#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001695private:
1696 promise(const promise& __rhs);
1697public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001698#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001699 ~promise();
1700
1701 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001702#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001704 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001705 {
1706 promise(std::move(__rhs)).swap(*this);
1707 return *this;
1708 }
1709 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001710#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001711private:
1712 promise& operator=(const promise& __rhs);
1713public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001714#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001715 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001716 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001717
1718 // retrieving the result
1719 future<void> get_future();
1720
1721 // setting the result
1722 void set_value();
1723 void set_exception(exception_ptr __p);
1724
1725 // setting the result with deferred notification
1726 void set_value_at_thread_exit();
1727 void set_exception_at_thread_exit(exception_ptr __p);
1728};
1729
1730template <class _Alloc>
1731promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1732{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001733 typedef __assoc_sub_state_alloc<_Alloc> _State;
1734 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001735 typedef __allocator_destructor<_A2> _D2;
1736 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001737 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1738 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1739 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001740}
1741
Howard Hinnant99968442011-11-29 18:15:50 +00001742template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001743inline _LIBCPP_INLINE_VISIBILITY
1744void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001745swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001746{
1747 __x.swap(__y);
1748}
1749
Howard Hinnant99968442011-11-29 18:15:50 +00001750template <class _Rp, class _Alloc>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001751 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001752 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001753
Howard Hinnant54da3382010-08-30 18:46:21 +00001754#ifndef _LIBCPP_HAS_NO_VARIADICS
1755
1756// packaged_task
1757
1758template<class _Fp> class __packaged_task_base;
1759
Howard Hinnant99968442011-11-29 18:15:50 +00001760template<class _Rp, class ..._ArgTypes>
1761class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001762{
1763 __packaged_task_base(const __packaged_task_base&);
1764 __packaged_task_base& operator=(const __packaged_task_base&);
1765public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001766 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001767 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001768 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001769 virtual ~__packaged_task_base() {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001770 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001771 virtual void destroy() = 0;
1772 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001773 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001774};
1775
1776template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1777
Howard Hinnant99968442011-11-29 18:15:50 +00001778template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1779class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1780 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001781{
Howard Hinnant99968442011-11-29 18:15:50 +00001782 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001783public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001784 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001785 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001786 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001787 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001788 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001789 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001790 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001791 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001792 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001793 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001794 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001795 virtual void destroy();
1796 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001797 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001798};
1799
Howard Hinnant99968442011-11-29 18:15:50 +00001800template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001801void
Howard Hinnant99968442011-11-29 18:15:50 +00001802__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001803 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001804{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001805 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001806}
1807
Howard Hinnant99968442011-11-29 18:15:50 +00001808template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001809void
Howard Hinnant99968442011-11-29 18:15:50 +00001810__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001811{
Howard Hinnant99968442011-11-29 18:15:50 +00001812 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001813}
1814
Howard Hinnant99968442011-11-29 18:15:50 +00001815template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001816void
Howard Hinnant99968442011-11-29 18:15:50 +00001817__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001818{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001819 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1820 typedef allocator_traits<_Ap> _ATraits;
1821 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnant99968442011-11-29 18:15:50 +00001822 _Ap __a(__f_.second());
1823 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001824 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant54da3382010-08-30 18:46:21 +00001825}
1826
Howard Hinnant99968442011-11-29 18:15:50 +00001827template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1828_Rp
1829__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001830{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001831 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001832}
1833
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001834template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001835
Howard Hinnant99968442011-11-29 18:15:50 +00001836template<class _Rp, class ..._ArgTypes>
1837class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001838{
Howard Hinnant99968442011-11-29 18:15:50 +00001839 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant78f0de22013-01-21 17:26:55 +00001840 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001841 __base* __f_;
1842
1843public:
Howard Hinnant99968442011-11-29 18:15:50 +00001844 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001845
1846 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001847 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001848 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001849 template<class _Fp>
1850 __packaged_task_function(_Fp&& __f);
1851 template<class _Fp, class _Alloc>
1852 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001853
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001854 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1855 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001856
1857 __packaged_task_function(const __packaged_task_function&) = delete;
1858 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1859
1860 ~__packaged_task_function();
1861
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001862 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001863
Howard Hinnant99968442011-11-29 18:15:50 +00001864 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001865};
1866
Howard Hinnant99968442011-11-29 18:15:50 +00001867template<class _Rp, class ..._ArgTypes>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001868__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001869{
1870 if (__f.__f_ == nullptr)
1871 __f_ = nullptr;
1872 else if (__f.__f_ == (__base*)&__f.__buf_)
1873 {
1874 __f_ = (__base*)&__buf_;
1875 __f.__f_->__move_to(__f_);
1876 }
1877 else
1878 {
1879 __f_ = __f.__f_;
1880 __f.__f_ = nullptr;
1881 }
1882}
1883
Howard Hinnant99968442011-11-29 18:15:50 +00001884template<class _Rp, class ..._ArgTypes>
1885template <class _Fp>
1886__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001887 : __f_(nullptr)
1888{
Marshall Clowf1264e72014-04-07 13:32:26 +00001889 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnant99968442011-11-29 18:15:50 +00001890 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001891 if (sizeof(_FF) <= sizeof(__buf_))
1892 {
1893 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001894 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001895 }
1896 else
1897 {
Howard Hinnant99968442011-11-29 18:15:50 +00001898 typedef allocator<_FF> _Ap;
1899 _Ap __a;
1900 typedef __allocator_destructor<_Ap> _Dp;
1901 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1902 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001903 __f_ = __hold.release();
1904 }
1905}
1906
Howard Hinnant99968442011-11-29 18:15:50 +00001907template<class _Rp, class ..._ArgTypes>
1908template <class _Fp, class _Alloc>
1909__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1910 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001911 : __f_(nullptr)
1912{
Marshall Clowf1264e72014-04-07 13:32:26 +00001913 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnant99968442011-11-29 18:15:50 +00001914 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001915 if (sizeof(_FF) <= sizeof(__buf_))
1916 {
1917 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001918 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001919 }
1920 else
1921 {
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001922 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +00001923 _Ap __a(__a0);
1924 typedef __allocator_destructor<_Ap> _Dp;
1925 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001926 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1927 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1928 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnant54da3382010-08-30 18:46:21 +00001929 }
1930}
1931
Howard Hinnant99968442011-11-29 18:15:50 +00001932template<class _Rp, class ..._ArgTypes>
1933__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001934__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001935{
1936 if (__f_ == (__base*)&__buf_)
1937 __f_->destroy();
1938 else if (__f_)
1939 __f_->destroy_deallocate();
1940 __f_ = nullptr;
1941 if (__f.__f_ == nullptr)
1942 __f_ = nullptr;
1943 else if (__f.__f_ == (__base*)&__f.__buf_)
1944 {
1945 __f_ = (__base*)&__buf_;
1946 __f.__f_->__move_to(__f_);
1947 }
1948 else
1949 {
1950 __f_ = __f.__f_;
1951 __f.__f_ = nullptr;
1952 }
Argyrios Kyrtzidis1dc6f7a2012-10-13 02:03:45 +00001953 return *this;
Howard Hinnant54da3382010-08-30 18:46:21 +00001954}
1955
Howard Hinnant99968442011-11-29 18:15:50 +00001956template<class _Rp, class ..._ArgTypes>
1957__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001958{
1959 if (__f_ == (__base*)&__buf_)
1960 __f_->destroy();
1961 else if (__f_)
1962 __f_->destroy_deallocate();
1963}
1964
Howard Hinnant99968442011-11-29 18:15:50 +00001965template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001966void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001967__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001968{
1969 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1970 {
1971 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1972 __base* __t = (__base*)&__tempbuf;
1973 __f_->__move_to(__t);
1974 __f_->destroy();
1975 __f_ = nullptr;
1976 __f.__f_->__move_to((__base*)&__buf_);
1977 __f.__f_->destroy();
1978 __f.__f_ = nullptr;
1979 __f_ = (__base*)&__buf_;
1980 __t->__move_to((__base*)&__f.__buf_);
1981 __t->destroy();
1982 __f.__f_ = (__base*)&__f.__buf_;
1983 }
1984 else if (__f_ == (__base*)&__buf_)
1985 {
1986 __f_->__move_to((__base*)&__f.__buf_);
1987 __f_->destroy();
1988 __f_ = __f.__f_;
1989 __f.__f_ = (__base*)&__f.__buf_;
1990 }
1991 else if (__f.__f_ == (__base*)&__f.__buf_)
1992 {
1993 __f.__f_->__move_to((__base*)&__buf_);
1994 __f.__f_->destroy();
1995 __f.__f_ = __f_;
1996 __f_ = (__base*)&__buf_;
1997 }
1998 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001999 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002000}
2001
Howard Hinnant99968442011-11-29 18:15:50 +00002002template<class _Rp, class ..._ArgTypes>
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002003inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002004_Rp
2005__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00002006{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002007 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002008}
2009
Howard Hinnant99968442011-11-29 18:15:50 +00002010template<class _Rp, class ..._ArgTypes>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002011class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002012{
2013public:
Howard Hinnant99968442011-11-29 18:15:50 +00002014 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00002015
2016private:
2017 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2018 promise<result_type> __p_;
2019
2020public:
2021 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002022 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002023 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002024 template <class _Fp,
2025 class = typename enable_if
2026 <
2027 !is_same<
2028 typename decay<_Fp>::type,
2029 packaged_task
2030 >::value
2031 >::type
2032 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002033 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002034 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002035 template <class _Fp, class _Allocator,
2036 class = typename enable_if
2037 <
2038 !is_same<
2039 typename decay<_Fp>::type,
2040 packaged_task
2041 >::value
2042 >::type
2043 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002044 _LIBCPP_INLINE_VISIBILITY
Marshall Clow07546f32015-06-30 14:16:49 +00002045 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnant99968442011-11-29 18:15:50 +00002046 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002047 __p_(allocator_arg, __a) {}
2048 // ~packaged_task() = default;
2049
2050 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002051 packaged_task(const packaged_task&) = delete;
2052 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002053
2054 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002055 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002056 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002057 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002059 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002060 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002061 __f_ = _VSTD::move(__other.__f_);
2062 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002063 return *this;
2064 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002066 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002067 {
2068 __f_.swap(__other.__f_);
2069 __p_.swap(__other.__p_);
2070 }
2071
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002072 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002073 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002074
2075 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002077 future<result_type> get_future() {return __p_.get_future();}
2078
2079 // execution
2080 void operator()(_ArgTypes... __args);
2081 void make_ready_at_thread_exit(_ArgTypes... __args);
2082
2083 void reset();
2084};
2085
Howard Hinnant99968442011-11-29 18:15:50 +00002086template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002087void
Howard Hinnant99968442011-11-29 18:15:50 +00002088packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002089{
Marshall Clowa1899742015-09-03 15:11:32 +00002090#ifndef _LIBCPP_NO_EXCEPTIONS
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002091 if (__p_.__state_ == nullptr)
2092 throw future_error(make_error_code(future_errc::no_state));
2093 if (__p_.__state_->__has_value())
2094 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant54da3382010-08-30 18:46:21 +00002095 try
2096 {
2097#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002098 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002099#ifndef _LIBCPP_NO_EXCEPTIONS
2100 }
2101 catch (...)
2102 {
2103 __p_.set_exception(current_exception());
2104 }
2105#endif // _LIBCPP_NO_EXCEPTIONS
2106}
2107
Howard Hinnant99968442011-11-29 18:15:50 +00002108template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002109void
Howard Hinnant99968442011-11-29 18:15:50 +00002110packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002111{
Marshall Clowa1899742015-09-03 15:11:32 +00002112#ifndef _LIBCPP_NO_EXCEPTIONS
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002113 if (__p_.__state_ == nullptr)
2114 throw future_error(make_error_code(future_errc::no_state));
2115 if (__p_.__state_->__has_value())
2116 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant54da3382010-08-30 18:46:21 +00002117 try
2118 {
2119#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002120 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002121#ifndef _LIBCPP_NO_EXCEPTIONS
2122 }
2123 catch (...)
2124 {
2125 __p_.set_exception_at_thread_exit(current_exception());
2126 }
2127#endif // _LIBCPP_NO_EXCEPTIONS
2128}
2129
Howard Hinnant99968442011-11-29 18:15:50 +00002130template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002131void
Howard Hinnant99968442011-11-29 18:15:50 +00002132packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002133{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002134#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002135 if (!valid())
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002136 throw future_error(make_error_code(future_errc::no_state));
2137#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002138 __p_ = promise<result_type>();
2139}
2140
2141template<class ..._ArgTypes>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002142class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002143{
2144public:
2145 typedef void result_type;
2146
2147private:
2148 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2149 promise<result_type> __p_;
2150
2151public:
2152 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002153 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002154 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002155 template <class _Fp,
2156 class = typename enable_if
2157 <
2158 !is_same<
2159 typename decay<_Fp>::type,
2160 packaged_task
2161 >::value
2162 >::type
2163 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002164 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002165 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002166 template <class _Fp, class _Allocator,
2167 class = typename enable_if
2168 <
2169 !is_same<
2170 typename decay<_Fp>::type,
2171 packaged_task
2172 >::value
2173 >::type
2174 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002175 _LIBCPP_INLINE_VISIBILITY
Marshall Clow5706c372015-06-30 18:28:35 +00002176 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnant99968442011-11-29 18:15:50 +00002177 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002178 __p_(allocator_arg, __a) {}
2179 // ~packaged_task() = default;
2180
2181 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002182 packaged_task(const packaged_task&) = delete;
2183 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002184
2185 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002186 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002187 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002188 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002190 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002191 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002192 __f_ = _VSTD::move(__other.__f_);
2193 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002194 return *this;
2195 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002196 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002197 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002198 {
2199 __f_.swap(__other.__f_);
2200 __p_.swap(__other.__p_);
2201 }
2202
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002203 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002204 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002205
2206 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002207 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002208 future<result_type> get_future() {return __p_.get_future();}
2209
2210 // execution
2211 void operator()(_ArgTypes... __args);
2212 void make_ready_at_thread_exit(_ArgTypes... __args);
2213
2214 void reset();
2215};
2216
2217template<class ..._ArgTypes>
2218void
2219packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2220{
Marshall Clowa1899742015-09-03 15:11:32 +00002221#ifndef _LIBCPP_NO_EXCEPTIONS
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002222 if (__p_.__state_ == nullptr)
2223 throw future_error(make_error_code(future_errc::no_state));
2224 if (__p_.__state_->__has_value())
2225 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant54da3382010-08-30 18:46:21 +00002226 try
2227 {
2228#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002229 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002230 __p_.set_value();
2231#ifndef _LIBCPP_NO_EXCEPTIONS
2232 }
2233 catch (...)
2234 {
2235 __p_.set_exception(current_exception());
2236 }
2237#endif // _LIBCPP_NO_EXCEPTIONS
2238}
2239
2240template<class ..._ArgTypes>
2241void
2242packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2243{
Marshall Clowa1899742015-09-03 15:11:32 +00002244#ifndef _LIBCPP_NO_EXCEPTIONS
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002245 if (__p_.__state_ == nullptr)
2246 throw future_error(make_error_code(future_errc::no_state));
2247 if (__p_.__state_->__has_value())
2248 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant54da3382010-08-30 18:46:21 +00002249 try
2250 {
2251#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002252 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002253 __p_.set_value_at_thread_exit();
2254#ifndef _LIBCPP_NO_EXCEPTIONS
2255 }
2256 catch (...)
2257 {
2258 __p_.set_exception_at_thread_exit(current_exception());
2259 }
2260#endif // _LIBCPP_NO_EXCEPTIONS
2261}
2262
2263template<class ..._ArgTypes>
2264void
2265packaged_task<void(_ArgTypes...)>::reset()
2266{
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002267#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002268 if (!valid())
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002269 throw future_error(make_error_code(future_errc::no_state));
2270#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002271 __p_ = promise<result_type>();
2272}
2273
2274template <class _Callable>
2275inline _LIBCPP_INLINE_VISIBILITY
2276void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002277swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002278{
2279 __x.swap(__y);
2280}
2281
2282template <class _Callable, class _Alloc>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002283struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002284 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002285
Howard Hinnant99968442011-11-29 18:15:50 +00002286template <class _Rp, class _Fp>
2287future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002288#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002289__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002290#else
Howard Hinnant99968442011-11-29 18:15:50 +00002291__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002292#endif
2293{
Howard Hinnant99968442011-11-29 18:15:50 +00002294 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2295 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2296 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002297}
2298
Howard Hinnant99968442011-11-29 18:15:50 +00002299template <class _Rp, class _Fp>
2300future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002301#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002302__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002303#else
Howard Hinnant99968442011-11-29 18:15:50 +00002304__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002305#endif
2306{
Howard Hinnant99968442011-11-29 18:15:50 +00002307 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2308 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2309 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2310 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002311}
2312
Howard Hinnant99968442011-11-29 18:15:50 +00002313template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002314class __async_func
2315{
Howard Hinnant99968442011-11-29 18:15:50 +00002316 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002317
2318public:
Howard Hinnant99968442011-11-29 18:15:50 +00002319 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002320
2321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002322 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002323 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002324
2325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002326 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002327
Howard Hinnant99968442011-11-29 18:15:50 +00002328 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002329 {
2330 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2331 return __execute(_Index());
2332 }
2333private:
2334 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002335 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002336 __execute(__tuple_indices<_Indices...>)
2337 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002338 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002339 }
2340};
2341
Marshall Clow3b3108e2013-11-03 22:06:53 +00002342inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clowad2a6002013-11-03 15:43:35 +00002343{ return (int(__policy) & int(__value)) != 0; }
2344
Howard Hinnant99968442011-11-29 18:15:50 +00002345template <class _Fp, class... _Args>
2346future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2347async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002348{
Howard Hinnant99968442011-11-29 18:15:50 +00002349 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2350 typedef typename _BF::_Rp _Rp;
Marshall Clowad2a6002013-11-03 15:43:35 +00002351
2352#ifndef _LIBCPP_NO_EXCEPTIONS
2353 try
2354 {
2355#endif
2356 if (__does_policy_contain(__policy, launch::async))
2357 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002358 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clowad2a6002013-11-03 15:43:35 +00002359#ifndef _LIBCPP_NO_EXCEPTIONS
2360 }
2361 catch ( ... ) { if (__policy == launch::async) throw ; }
2362#endif
2363
2364 if (__does_policy_contain(__policy, launch::deferred))
2365 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002366 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clowad2a6002013-11-03 15:43:35 +00002367 return future<_Rp>{};
Howard Hinnant54da3382010-08-30 18:46:21 +00002368}
2369
Howard Hinnant99968442011-11-29 18:15:50 +00002370template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002371inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002372future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2373async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002374{
Howard Hinnant99968442011-11-29 18:15:50 +00002375 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002376 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002377}
2378
2379#endif // _LIBCPP_HAS_NO_VARIADICS
2380
Howard Hinnante6e4d012010-09-03 21:46:37 +00002381// shared_future
2382
Howard Hinnant99968442011-11-29 18:15:50 +00002383template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002384class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002385{
Howard Hinnant99968442011-11-29 18:15:50 +00002386 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002387
2388public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002389 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002390 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002392 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2393 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002394#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002396 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002397 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002398 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002399 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002400 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002401#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002402 ~shared_future();
2403 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002404#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002405 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002406 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002407 {
2408 shared_future(std::move(__rhs)).swap(*this);
2409 return *this;
2410 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002411#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002412
2413 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002414 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002415 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002416
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002418 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002419
2420 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002422 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002423
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002424 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002425 void wait() const {__state_->wait();}
2426 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002427 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002428 future_status
2429 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2430 {return __state_->wait_for(__rel_time);}
2431 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002432 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002433 future_status
2434 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2435 {return __state_->wait_until(__abs_time);}
2436};
2437
Howard Hinnant99968442011-11-29 18:15:50 +00002438template <class _Rp>
2439shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002440{
2441 if (__state_)
2442 __state_->__release_shared();
2443}
2444
Howard Hinnant99968442011-11-29 18:15:50 +00002445template <class _Rp>
2446shared_future<_Rp>&
2447shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002448{
2449 if (__rhs.__state_)
2450 __rhs.__state_->__add_shared();
2451 if (__state_)
2452 __state_->__release_shared();
2453 __state_ = __rhs.__state_;
2454 return *this;
2455}
2456
Howard Hinnant99968442011-11-29 18:15:50 +00002457template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002458class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002459{
Howard Hinnant99968442011-11-29 18:15:50 +00002460 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002461
2462public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002464 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002466 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2467 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002468#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002469 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002470 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002471 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002473 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002474 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002475#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002476 ~shared_future();
2477 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002478#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002479 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002480 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002481 {
2482 shared_future(std::move(__rhs)).swap(*this);
2483 return *this;
2484 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002485#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002486
2487 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002488 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002489 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002490
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002491 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002492 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002493
2494 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002495 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002496 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002497
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002498 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002499 void wait() const {__state_->wait();}
2500 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002501 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002502 future_status
2503 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2504 {return __state_->wait_for(__rel_time);}
2505 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002506 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002507 future_status
2508 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2509 {return __state_->wait_until(__abs_time);}
2510};
2511
Howard Hinnant99968442011-11-29 18:15:50 +00002512template <class _Rp>
2513shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002514{
2515 if (__state_)
2516 __state_->__release_shared();
2517}
2518
Howard Hinnant99968442011-11-29 18:15:50 +00002519template <class _Rp>
2520shared_future<_Rp&>&
2521shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002522{
2523 if (__rhs.__state_)
2524 __rhs.__state_->__add_shared();
2525 if (__state_)
2526 __state_->__release_shared();
2527 __state_ = __rhs.__state_;
2528 return *this;
2529}
2530
2531template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00002532class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002533{
2534 __assoc_sub_state* __state_;
2535
2536public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002537 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002538 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002540 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2541 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002542#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002543 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002544 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002545 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002547 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002548 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002549#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002550 ~shared_future();
2551 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002552#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002553 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002554 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002555 {
2556 shared_future(std::move(__rhs)).swap(*this);
2557 return *this;
2558 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002559#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002560
2561 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002562 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002563 void get() const {__state_->copy();}
2564
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002566 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002567
2568 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002569 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002570 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002571
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002572 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002573 void wait() const {__state_->wait();}
2574 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002575 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002576 future_status
2577 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2578 {return __state_->wait_for(__rel_time);}
2579 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002580 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002581 future_status
2582 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2583 {return __state_->wait_until(__abs_time);}
2584};
2585
Howard Hinnant99968442011-11-29 18:15:50 +00002586template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002587inline _LIBCPP_INLINE_VISIBILITY
2588void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002589swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002590{
2591 __x.swap(__y);
2592}
2593
Howard Hinnant99968442011-11-29 18:15:50 +00002594template <class _Rp>
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002595inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002596shared_future<_Rp>
2597future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002598{
Howard Hinnant99968442011-11-29 18:15:50 +00002599 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002600}
2601
Howard Hinnant99968442011-11-29 18:15:50 +00002602template <class _Rp>
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002603inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002604shared_future<_Rp&>
2605future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002606{
Howard Hinnant99968442011-11-29 18:15:50 +00002607 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002608}
2609
Howard Hinnanta4451512010-12-02 16:45:21 +00002610#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2611
Dan Albert1d4a1ed2016-05-25 22:36:09 -07002612inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7de47902010-11-30 20:23:32 +00002613shared_future<void>
2614future<void>::share()
2615{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002616 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002617}
2618
Howard Hinnanta4451512010-12-02 16:45:21 +00002619#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2620
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002621_LIBCPP_END_NAMESPACE_STD
2622
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +00002623#endif // !_LIBCPP_HAS_NO_THREADS
2624
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002625#endif // _LIBCPP_FUTURE