blob: d1d42f6a727444e7f451e696bbae437ae5738d1c [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
Howard Hinnantee11c312010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc51e1022010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000022 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000023 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000024 no_state,
25 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000026};
27
28enum class launch
29{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000033};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000045
Howard Hinnant22448042012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
Marshall Clowd4a669c2016-11-14 18:56:24 +000053 explicit future_error(future_errc); // C++17
Howard Hinnant22448042012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000056};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000073
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
Howard Hinnant22448042012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
Howard Hinnant22448042012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
Howard Hinnant22448042012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
Howard Hinnant22448042012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
Howard Hinnant22448042012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
Howard Hinnant22448042012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
Howard Hinnant22448042012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantc51e1022010-05-11 19:42:16 +0000311template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000312 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000316 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantc566dc32010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +0000325 typedef R result_type; // extension
Howard Hinnantc51e1022010-05-11 19:42:16 +0000326
327 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
Marshall Clowc317e022015-06-30 14:16:49 +0000332 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000333 ~packaged_task();
334
335 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000340 packaged_task(packaged_task&& other) noexcept;
341 packaged_task& operator=(packaged_task&& other) noexcept;
342 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000343
Howard Hinnant22448042012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000358
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000375#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000377#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000378#error <future> is not supported on this single threaded system
379#else // !_LIBCPP_HAS_NO_THREADS
380
Howard Hinnantc51e1022010-05-11 19:42:16 +0000381_LIBCPP_BEGIN_NAMESPACE_STD
382
383//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000384_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000385{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000386 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000388 no_state,
389 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000391_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000392
Howard Hinnant684902d2010-09-22 14:16:26 +0000393template <>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000394struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000395
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000396#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397template <>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000398struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000399#endif
400
Howard Hinnantc51e1022010-05-11 19:42:16 +0000401//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000402_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000403{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000404 async = 1,
405 deferred = 2,
406 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000409
Howard Hinnantda760a82013-06-29 18:38:17 +0000410#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411
412#ifdef _LIBCXX_UNDERLYING_TYPE
413typedef underlying_type<launch>::type __launch_underlying_type;
414#else
415typedef int __launch_underlying_type;
416#endif
417
418inline _LIBCPP_INLINE_VISIBILITY
419_LIBCPP_CONSTEXPR
420launch
421operator&(launch __x, launch __y)
422{
423 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
424 static_cast<__launch_underlying_type>(__y));
425}
426
427inline _LIBCPP_INLINE_VISIBILITY
428_LIBCPP_CONSTEXPR
429launch
430operator|(launch __x, launch __y)
431{
432 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
433 static_cast<__launch_underlying_type>(__y));
434}
435
436inline _LIBCPP_INLINE_VISIBILITY
437_LIBCPP_CONSTEXPR
438launch
439operator^(launch __x, launch __y)
440{
441 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
442 static_cast<__launch_underlying_type>(__y));
443}
444
445inline _LIBCPP_INLINE_VISIBILITY
446_LIBCPP_CONSTEXPR
447launch
448operator~(launch __x)
449{
Howard Hinnant373d7602013-07-02 18:01:41 +0000450 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000451}
452
453inline _LIBCPP_INLINE_VISIBILITY
454launch&
455operator&=(launch& __x, launch __y)
456{
457 __x = __x & __y; return __x;
458}
459
460inline _LIBCPP_INLINE_VISIBILITY
461launch&
462operator|=(launch& __x, launch __y)
463{
464 __x = __x | __y; return __x;
465}
466
467inline _LIBCPP_INLINE_VISIBILITY
468launch&
469operator^=(launch& __x, launch __y)
470{
471 __x = __x ^ __y; return __x;
472}
473
474#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
475
Howard Hinnantc51e1022010-05-11 19:42:16 +0000476//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000477_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000478{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479 ready,
480 timeout,
481 deferred
482};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000483_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000484
Howard Hinnant8331b762013-03-06 23:30:19 +0000485_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000486const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000487
488inline _LIBCPP_INLINE_VISIBILITY
489error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000490make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000491{
492 return error_code(static_cast<int>(__e), future_category());
493}
494
495inline _LIBCPP_INLINE_VISIBILITY
496error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000497make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000498{
499 return error_condition(static_cast<int>(__e), future_category());
500}
501
Howard Hinnant684902d2010-09-22 14:16:26 +0000502class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000503 : public logic_error
504{
505 error_code __ec_;
506public:
507 future_error(error_code __ec);
Marshall Clowd4a669c2016-11-14 18:56:24 +0000508#if _LIBCPP_STD_VERS > 14
509 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
510#endif
Howard Hinnant684902d2010-09-22 14:16:26 +0000511 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000512 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000513
514 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000515};
516
Marshall Clow8fea1612016-08-25 15:09:01 +0000517_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
Eric Fiselier43641592015-10-02 21:25:15 +0000518void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000519{
520#ifndef _LIBCPP_NO_EXCEPTIONS
521 throw future_error(make_error_code(_Ev));
522#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000523 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000524 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000525#endif
526}
527
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000528class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000529 : public __shared_count
530{
531protected:
532 exception_ptr __exception_;
533 mutable mutex __mut_;
534 mutable condition_variable __cv_;
535 unsigned __state_;
536
Howard Hinnant719bda32011-05-28 14:41:13 +0000537 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000538 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000539public:
540 enum
541 {
542 __constructed = 1,
543 __future_attached = 2,
544 ready = 4,
545 deferred = 8
546 };
547
Howard Hinnant684902d2010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000549 __assoc_sub_state() : __state_(0) {}
550
Howard Hinnant684902d2010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000552 bool __has_value() const
553 {return (__state_ & __constructed) || (__exception_ != nullptr);}
554
Howard Hinnant684902d2010-09-22 14:16:26 +0000555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante667ecc2013-01-14 20:01:24 +0000556 void __set_future_attached()
557 {
558 lock_guard<mutex> __lk(__mut_);
559 __state_ |= __future_attached;
560 }
Howard Hinnant684902d2010-09-22 14:16:26 +0000561 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000562 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000563
Howard Hinnant684902d2010-09-22 14:16:26 +0000564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000565 void __set_deferred() {__state_ |= deferred;}
566
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000568 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000569 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000570
571 void set_value();
572 void set_value_at_thread_exit();
573
574 void set_exception(exception_ptr __p);
575 void set_exception_at_thread_exit(exception_ptr __p);
576
577 void copy();
578
Howard Hinnantccdd2032010-08-30 18:46:21 +0000579 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000580 template <class _Rep, class _Period>
581 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000583 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
584 template <class _Clock, class _Duration>
585 future_status
586 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000587
588 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000589};
590
Howard Hinnantf4712b92010-08-28 21:01:06 +0000591template <class _Clock, class _Duration>
592future_status
593__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
594{
595 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000596 if (__state_ & deferred)
597 return future_status::deferred;
598 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000599 __cv_.wait_until(__lk, __abs_time);
600 if (__state_ & ready)
601 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000602 return future_status::timeout;
603}
604
605template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000606inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000607future_status
608__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
609{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000610 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000611}
612
Howard Hinnantc834c512011-11-29 18:15:50 +0000613template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000614class __assoc_state
615 : public __assoc_sub_state
616{
617 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000618 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000619protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000620 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000621
Howard Hinnant719bda32011-05-28 14:41:13 +0000622 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000623public:
624
625 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000626#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000627 void set_value(_Arg&& __arg);
628#else
629 void set_value(_Arg& __arg);
630#endif
631
632 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000633#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000634 void set_value_at_thread_exit(_Arg&& __arg);
635#else
636 void set_value_at_thread_exit(_Arg& __arg);
637#endif
638
Howard Hinnantc834c512011-11-29 18:15:50 +0000639 _Rp move();
640 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000641};
642
Howard Hinnantc834c512011-11-29 18:15:50 +0000643template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000644void
Howard Hinnantc834c512011-11-29 18:15:50 +0000645__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000646{
647 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000648 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000649 delete this;
650}
651
Howard Hinnantc834c512011-11-29 18:15:50 +0000652template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000653template <class _Arg>
654void
Howard Hinnant74279a52010-09-04 23:28:19 +0000655#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000656__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000657#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000658__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000659#endif
660{
661 unique_lock<mutex> __lk(this->__mut_);
662 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000663 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000664 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000665 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000666 __cv_.notify_all();
667}
668
Howard Hinnantc834c512011-11-29 18:15:50 +0000669template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000670template <class _Arg>
671void
Howard Hinnant74279a52010-09-04 23:28:19 +0000672#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000673__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000674#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000675__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000676#endif
677{
678 unique_lock<mutex> __lk(this->__mut_);
679 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000680 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000681 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000682 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000683 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000684}
685
Howard Hinnantc834c512011-11-29 18:15:50 +0000686template <class _Rp>
687_Rp
688__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000689{
690 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000691 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000692 if (this->__exception_ != nullptr)
693 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000694 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000695}
696
Howard Hinnantc834c512011-11-29 18:15:50 +0000697template <class _Rp>
698typename add_lvalue_reference<_Rp>::type
699__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000700{
701 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000702 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000703 if (this->__exception_ != nullptr)
704 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000705 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000706}
707
Howard Hinnantc834c512011-11-29 18:15:50 +0000708template <class _Rp>
709class __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000710 : public __assoc_sub_state
711{
712 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000713 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000714protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000715 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000716
Howard Hinnant719bda32011-05-28 14:41:13 +0000717 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000718public:
719
Howard Hinnantc834c512011-11-29 18:15:50 +0000720 void set_value(_Rp& __arg);
721 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000722
Howard Hinnantc834c512011-11-29 18:15:50 +0000723 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000724};
725
Howard Hinnantc834c512011-11-29 18:15:50 +0000726template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000727void
Howard Hinnantc834c512011-11-29 18:15:50 +0000728__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000729{
730 delete this;
731}
732
Howard Hinnantc834c512011-11-29 18:15:50 +0000733template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000734void
Howard Hinnantc834c512011-11-29 18:15:50 +0000735__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000736{
737 unique_lock<mutex> __lk(this->__mut_);
738 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000739 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000740 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000741 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000742 __cv_.notify_all();
743}
744
Howard Hinnantc834c512011-11-29 18:15:50 +0000745template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000746void
Howard Hinnantc834c512011-11-29 18:15:50 +0000747__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000748{
749 unique_lock<mutex> __lk(this->__mut_);
750 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000751 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000752 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000753 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000754 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000755}
756
Howard Hinnantc834c512011-11-29 18:15:50 +0000757template <class _Rp>
758_Rp&
759__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000760{
761 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000762 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000763 if (this->__exception_ != nullptr)
764 rethrow_exception(this->__exception_);
765 return *__value_;
766}
767
Howard Hinnantc834c512011-11-29 18:15:50 +0000768template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000769class __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000770 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000771{
Howard Hinnantc834c512011-11-29 18:15:50 +0000772 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000773 _Alloc __alloc_;
774
Howard Hinnant719bda32011-05-28 14:41:13 +0000775 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000776public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000778 explicit __assoc_state_alloc(const _Alloc& __a)
779 : __alloc_(__a) {}
780};
781
Howard Hinnantc834c512011-11-29 18:15:50 +0000782template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000783void
Howard Hinnantc834c512011-11-29 18:15:50 +0000784__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000785{
786 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000787 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000788 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
789 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000790 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000791 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000792 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000793 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000794}
795
Howard Hinnantc834c512011-11-29 18:15:50 +0000796template <class _Rp, class _Alloc>
797class __assoc_state_alloc<_Rp&, _Alloc>
798 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000799{
Howard Hinnantc834c512011-11-29 18:15:50 +0000800 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000801 _Alloc __alloc_;
802
Howard Hinnant719bda32011-05-28 14:41:13 +0000803 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000804public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000805 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000806 explicit __assoc_state_alloc(const _Alloc& __a)
807 : __alloc_(__a) {}
808};
809
Howard Hinnantc834c512011-11-29 18:15:50 +0000810template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000811void
Howard Hinnantc834c512011-11-29 18:15:50 +0000812__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000813{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000814 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
815 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000816 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000817 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000818 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000819 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000820}
821
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000822template <class _Alloc>
823class __assoc_sub_state_alloc
824 : public __assoc_sub_state
825{
826 typedef __assoc_sub_state base;
827 _Alloc __alloc_;
828
Howard Hinnant719bda32011-05-28 14:41:13 +0000829 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000830public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000831 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000832 explicit __assoc_sub_state_alloc(const _Alloc& __a)
833 : __alloc_(__a) {}
834};
835
836template <class _Alloc>
837void
Howard Hinnant719bda32011-05-28 14:41:13 +0000838__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000839{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000840 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
841 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000842 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000843 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000844 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000845 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000846}
847
Howard Hinnantc834c512011-11-29 18:15:50 +0000848template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000849class __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000850 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000851{
Howard Hinnantc834c512011-11-29 18:15:50 +0000852 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000853
Howard Hinnantc834c512011-11-29 18:15:50 +0000854 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000855
856public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000857#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000858 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000859 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000860#endif
861
862 virtual void __execute();
863};
864
Howard Hinnant74279a52010-09-04 23:28:19 +0000865#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000866
Howard Hinnantc834c512011-11-29 18:15:50 +0000867template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000868inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000869__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
870 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000871{
872 this->__set_deferred();
873}
874
Howard Hinnant74279a52010-09-04 23:28:19 +0000875#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000876
Howard Hinnantc834c512011-11-29 18:15:50 +0000877template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000878void
Howard Hinnantc834c512011-11-29 18:15:50 +0000879__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000880{
881#ifndef _LIBCPP_NO_EXCEPTIONS
882 try
883 {
884#endif // _LIBCPP_NO_EXCEPTIONS
885 this->set_value(__func_());
886#ifndef _LIBCPP_NO_EXCEPTIONS
887 }
888 catch (...)
889 {
890 this->set_exception(current_exception());
891 }
892#endif // _LIBCPP_NO_EXCEPTIONS
893}
894
Howard Hinnantc834c512011-11-29 18:15:50 +0000895template <class _Fp>
896class __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000897 : public __assoc_sub_state
898{
899 typedef __assoc_sub_state base;
900
Howard Hinnantc834c512011-11-29 18:15:50 +0000901 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000902
903public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000904#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000905 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000906 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000907#endif
908
909 virtual void __execute();
910};
911
Howard Hinnant74279a52010-09-04 23:28:19 +0000912#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000913
Howard Hinnantc834c512011-11-29 18:15:50 +0000914template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000915inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000916__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
917 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000918{
919 this->__set_deferred();
920}
921
Howard Hinnant74279a52010-09-04 23:28:19 +0000922#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000923
Howard Hinnantc834c512011-11-29 18:15:50 +0000924template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000925void
Howard Hinnantc834c512011-11-29 18:15:50 +0000926__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000927{
928#ifndef _LIBCPP_NO_EXCEPTIONS
929 try
930 {
931#endif // _LIBCPP_NO_EXCEPTIONS
932 __func_();
933 this->set_value();
934#ifndef _LIBCPP_NO_EXCEPTIONS
935 }
936 catch (...)
937 {
938 this->set_exception(current_exception());
939 }
940#endif // _LIBCPP_NO_EXCEPTIONS
941}
942
Howard Hinnantc834c512011-11-29 18:15:50 +0000943template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000944class __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000945 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000946{
Howard Hinnantc834c512011-11-29 18:15:50 +0000947 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000948
Howard Hinnantc834c512011-11-29 18:15:50 +0000949 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000950
Howard Hinnant719bda32011-05-28 14:41:13 +0000951 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000952public:
953#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000954 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000955 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000956#endif
957
958 virtual void __execute();
959};
960
961#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
962
Howard Hinnantc834c512011-11-29 18:15:50 +0000963template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000964inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000965__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
966 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000967{
968}
969
970#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
971
Howard Hinnantc834c512011-11-29 18:15:50 +0000972template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000973void
Howard Hinnantc834c512011-11-29 18:15:50 +0000974__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000975{
976#ifndef _LIBCPP_NO_EXCEPTIONS
977 try
978 {
979#endif // _LIBCPP_NO_EXCEPTIONS
980 this->set_value(__func_());
981#ifndef _LIBCPP_NO_EXCEPTIONS
982 }
983 catch (...)
984 {
985 this->set_exception(current_exception());
986 }
987#endif // _LIBCPP_NO_EXCEPTIONS
988}
989
Howard Hinnantc834c512011-11-29 18:15:50 +0000990template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000991void
Howard Hinnantc834c512011-11-29 18:15:50 +0000992__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000993{
994 this->wait();
995 base::__on_zero_shared();
996}
997
Howard Hinnantc834c512011-11-29 18:15:50 +0000998template <class _Fp>
999class __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001000 : public __assoc_sub_state
1001{
1002 typedef __assoc_sub_state base;
1003
Howard Hinnantc834c512011-11-29 18:15:50 +00001004 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001005
Howard Hinnant719bda32011-05-28 14:41:13 +00001006 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001007public:
1008#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001009 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001010 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001011#endif
1012
1013 virtual void __execute();
1014};
1015
1016#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1017
Howard Hinnantc834c512011-11-29 18:15:50 +00001018template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001019inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001020__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1021 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001022{
1023}
1024
1025#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1026
Howard Hinnantc834c512011-11-29 18:15:50 +00001027template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001028void
Howard Hinnantc834c512011-11-29 18:15:50 +00001029__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001030{
1031#ifndef _LIBCPP_NO_EXCEPTIONS
1032 try
1033 {
1034#endif // _LIBCPP_NO_EXCEPTIONS
1035 __func_();
1036 this->set_value();
1037#ifndef _LIBCPP_NO_EXCEPTIONS
1038 }
1039 catch (...)
1040 {
1041 this->set_exception(current_exception());
1042 }
1043#endif // _LIBCPP_NO_EXCEPTIONS
1044}
1045
Howard Hinnantc834c512011-11-29 18:15:50 +00001046template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001047void
Howard Hinnantc834c512011-11-29 18:15:50 +00001048__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001049{
1050 this->wait();
1051 base::__on_zero_shared();
1052}
1053
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001054template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1055template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001056
1057// future
1058
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001059template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001060
Howard Hinnantc834c512011-11-29 18:15:50 +00001061template <class _Rp, class _Fp>
1062future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001063#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001064__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001065#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001066__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001067#endif
1068
Howard Hinnantc834c512011-11-29 18:15:50 +00001069template <class _Rp, class _Fp>
1070future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001071#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001072__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001073#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001074__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001075#endif
1076
Howard Hinnantc834c512011-11-29 18:15:50 +00001077template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001078class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001079{
Howard Hinnantc834c512011-11-29 18:15:50 +00001080 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001081
Howard Hinnantc834c512011-11-29 18:15:50 +00001082 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001083
1084 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001085 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001086
Howard Hinnant74279a52010-09-04 23:28:19 +00001087#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001088 template <class _R1, class _Fp>
1089 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1090 template <class _R1, class _Fp>
1091 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001092#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001093 template <class _R1, class _Fp>
1094 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1095 template <class _R1, class _Fp>
1096 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001097#endif
1098
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001099public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001100 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001101 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001102#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001103 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001104 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001105 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1106 future(const future&) = delete;
1107 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001108 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001109 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001110 {
1111 future(std::move(__rhs)).swap(*this);
1112 return *this;
1113 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001114#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001115private:
1116 future(const future&);
1117 future& operator=(const future&);
1118public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001119#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001120 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001121 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001122 shared_future<_Rp> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001123
1124 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001125 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001126
Howard Hinnant684902d2010-09-22 14:16:26 +00001127 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001128 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001129
1130 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001131 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001132 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001133
Howard Hinnant684902d2010-09-22 14:16:26 +00001134 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001135 void wait() const {__state_->wait();}
1136 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001137 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001138 future_status
1139 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1140 {return __state_->wait_for(__rel_time);}
1141 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001142 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001143 future_status
1144 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1145 {return __state_->wait_until(__abs_time);}
1146};
1147
Howard Hinnantc834c512011-11-29 18:15:50 +00001148template <class _Rp>
1149future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001150 : __state_(__state)
1151{
1152 if (__state_->__has_future_attached())
Eric Fiselier43641592015-10-02 21:25:15 +00001153 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001154 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001155 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001156}
1157
Howard Hinnantccdd2032010-08-30 18:46:21 +00001158struct __release_shared_count
1159{
1160 void operator()(__shared_count* p) {p->__release_shared();}
1161};
1162
Howard Hinnantc834c512011-11-29 18:15:50 +00001163template <class _Rp>
1164future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001165{
1166 if (__state_)
1167 __state_->__release_shared();
1168}
1169
Howard Hinnantc834c512011-11-29 18:15:50 +00001170template <class _Rp>
1171_Rp
1172future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001173{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001174 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001175 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001176 __state_ = nullptr;
1177 return __s->move();
1178}
1179
Howard Hinnantc834c512011-11-29 18:15:50 +00001180template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001181class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001182{
Howard Hinnantc834c512011-11-29 18:15:50 +00001183 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001184
Howard Hinnantc834c512011-11-29 18:15:50 +00001185 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001186
1187 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001188 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001189
Howard Hinnant74279a52010-09-04 23:28:19 +00001190#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001191 template <class _R1, class _Fp>
1192 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1193 template <class _R1, class _Fp>
1194 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001195#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001196 template <class _R1, class _Fp>
1197 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1198 template <class _R1, class _Fp>
1199 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001200#endif
1201
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001202public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001203 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001204 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001205#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001206 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001207 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001208 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1209 future(const future&) = delete;
1210 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001212 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001213 {
1214 future(std::move(__rhs)).swap(*this);
1215 return *this;
1216 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001217#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001218private:
1219 future(const future&);
1220 future& operator=(const future&);
1221public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001222#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001223 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001224 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001225 shared_future<_Rp&> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001226
1227 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001228 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001229
Howard Hinnant684902d2010-09-22 14:16:26 +00001230 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001231 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001232
1233 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001235 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001236
Howard Hinnant684902d2010-09-22 14:16:26 +00001237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001238 void wait() const {__state_->wait();}
1239 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001241 future_status
1242 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1243 {return __state_->wait_for(__rel_time);}
1244 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001246 future_status
1247 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1248 {return __state_->wait_until(__abs_time);}
1249};
1250
Howard Hinnantc834c512011-11-29 18:15:50 +00001251template <class _Rp>
1252future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001253 : __state_(__state)
1254{
1255 if (__state_->__has_future_attached())
Eric Fiselier43641592015-10-02 21:25:15 +00001256 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001257 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001258 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001259}
1260
Howard Hinnantc834c512011-11-29 18:15:50 +00001261template <class _Rp>
1262future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001263{
1264 if (__state_)
1265 __state_->__release_shared();
1266}
1267
Howard Hinnantc834c512011-11-29 18:15:50 +00001268template <class _Rp>
1269_Rp&
1270future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001271{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001272 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001273 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001274 __state_ = nullptr;
1275 return __s->copy();
1276}
1277
1278template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001279class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001280{
1281 __assoc_sub_state* __state_;
1282
1283 explicit future(__assoc_sub_state* __state);
1284
1285 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001286 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001287
Howard Hinnant74279a52010-09-04 23:28:19 +00001288#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001289 template <class _R1, class _Fp>
1290 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1291 template <class _R1, class _Fp>
1292 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001293#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001294 template <class _R1, class _Fp>
1295 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1296 template <class _R1, class _Fp>
1297 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001298#endif
1299
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001300public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001302 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001303#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001305 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001306 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1307 future(const future&) = delete;
1308 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001310 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001311 {
1312 future(std::move(__rhs)).swap(*this);
1313 return *this;
1314 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001315#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001316private:
1317 future(const future&);
1318 future& operator=(const future&);
1319public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001320#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001321 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001322 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001323 shared_future<void> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001324
1325 // retrieving the value
1326 void get();
1327
Howard Hinnant684902d2010-09-22 14:16:26 +00001328 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001329 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001330
1331 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001333 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001334
Howard Hinnant684902d2010-09-22 14:16:26 +00001335 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001336 void wait() const {__state_->wait();}
1337 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001338 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001339 future_status
1340 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1341 {return __state_->wait_for(__rel_time);}
1342 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001344 future_status
1345 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1346 {return __state_->wait_until(__abs_time);}
1347};
1348
Howard Hinnantc834c512011-11-29 18:15:50 +00001349template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001350inline _LIBCPP_INLINE_VISIBILITY
1351void
Howard Hinnant22448042012-07-21 17:46:55 +00001352swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001353{
1354 __x.swap(__y);
1355}
1356
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001357// promise<R>
1358
Howard Hinnant944510a2011-06-14 19:58:17 +00001359template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001360
Howard Hinnantc834c512011-11-29 18:15:50 +00001361template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001362class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001363{
Howard Hinnantc834c512011-11-29 18:15:50 +00001364 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001365
Howard Hinnant684902d2010-09-22 14:16:26 +00001366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001367 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001368
1369 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001370public:
1371 promise();
1372 template <class _Alloc>
1373 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001374#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001376 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001377 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1378 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001379#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001380private:
1381 promise(const promise& __rhs);
1382public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001383#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001384 ~promise();
1385
1386 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001389 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001390 {
1391 promise(std::move(__rhs)).swap(*this);
1392 return *this;
1393 }
1394 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001395#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001396private:
1397 promise& operator=(const promise& __rhs);
1398public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001399#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001401 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001402
1403 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001404 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001405
1406 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001407 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001408#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001409 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001410#endif
1411 void set_exception(exception_ptr __p);
1412
1413 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001414 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001415#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001416 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001417#endif
1418 void set_exception_at_thread_exit(exception_ptr __p);
1419};
1420
Howard Hinnantc834c512011-11-29 18:15:50 +00001421template <class _Rp>
1422promise<_Rp>::promise()
1423 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001424{
1425}
1426
Howard Hinnantc834c512011-11-29 18:15:50 +00001427template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001428template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001429promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001430{
Eric Fiselier0d109272014-10-23 06:24:45 +00001431 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1432 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001433 typedef __allocator_destructor<_A2> _D2;
1434 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001435 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1436 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1437 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001438}
1439
Howard Hinnantc834c512011-11-29 18:15:50 +00001440template <class _Rp>
1441promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001442{
1443 if (__state_)
1444 {
1445 if (!__state_->__has_value() && __state_->use_count() > 1)
1446 __state_->set_exception(make_exception_ptr(
1447 future_error(make_error_code(future_errc::broken_promise))
1448 ));
1449 __state_->__release_shared();
1450 }
1451}
1452
Howard Hinnantc834c512011-11-29 18:15:50 +00001453template <class _Rp>
1454future<_Rp>
1455promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001456{
1457 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001458 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001459 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001460}
1461
Howard Hinnantc834c512011-11-29 18:15:50 +00001462template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001463void
Howard Hinnantc834c512011-11-29 18:15:50 +00001464promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001465{
1466 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001467 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001468 __state_->set_value(__r);
1469}
1470
Howard Hinnant74279a52010-09-04 23:28:19 +00001471#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001472
Howard Hinnantc834c512011-11-29 18:15:50 +00001473template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001474void
Howard Hinnantc834c512011-11-29 18:15:50 +00001475promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001476{
1477 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001478 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001479 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001480}
1481
Howard Hinnant74279a52010-09-04 23:28:19 +00001482#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001483
Howard Hinnantc834c512011-11-29 18:15:50 +00001484template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001485void
Howard Hinnantc834c512011-11-29 18:15:50 +00001486promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001487{
Marshall Clow2b36f572016-05-16 16:55:32 +00001488 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001489 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001490 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001491 __state_->set_exception(__p);
1492}
1493
Howard Hinnantc834c512011-11-29 18:15:50 +00001494template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001495void
Howard Hinnantc834c512011-11-29 18:15:50 +00001496promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001497{
1498 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001499 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001500 __state_->set_value_at_thread_exit(__r);
1501}
1502
Howard Hinnant74279a52010-09-04 23:28:19 +00001503#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504
Howard Hinnantc834c512011-11-29 18:15:50 +00001505template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001506void
Howard Hinnantc834c512011-11-29 18:15:50 +00001507promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001508{
1509 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001510 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001511 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001512}
1513
Howard Hinnant74279a52010-09-04 23:28:19 +00001514#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001515
Howard Hinnantc834c512011-11-29 18:15:50 +00001516template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001517void
Howard Hinnantc834c512011-11-29 18:15:50 +00001518promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001519{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001520 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001521 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001522 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001523 __state_->set_exception_at_thread_exit(__p);
1524}
1525
1526// promise<R&>
1527
Howard Hinnantc834c512011-11-29 18:15:50 +00001528template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001529class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001530{
Howard Hinnantc834c512011-11-29 18:15:50 +00001531 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001532
Howard Hinnant684902d2010-09-22 14:16:26 +00001533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001534 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001535
1536 template <class> friend class packaged_task;
1537
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001538public:
1539 promise();
1540 template <class _Allocator>
1541 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001542#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001543 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001544 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001545 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1546 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001547#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001548private:
1549 promise(const promise& __rhs);
1550public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001551#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001552 ~promise();
1553
1554 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001555#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001557 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001558 {
1559 promise(std::move(__rhs)).swap(*this);
1560 return *this;
1561 }
1562 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001563#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001564private:
1565 promise& operator=(const promise& __rhs);
1566public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001567#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001569 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001570
1571 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001572 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001573
1574 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001575 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001576 void set_exception(exception_ptr __p);
1577
1578 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001579 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001580 void set_exception_at_thread_exit(exception_ptr __p);
1581};
1582
Howard Hinnantc834c512011-11-29 18:15:50 +00001583template <class _Rp>
1584promise<_Rp&>::promise()
1585 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001586{
1587}
1588
Howard Hinnantc834c512011-11-29 18:15:50 +00001589template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001590template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001591promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001592{
Eric Fiselier0d109272014-10-23 06:24:45 +00001593 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1594 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001595 typedef __allocator_destructor<_A2> _D2;
1596 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001597 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1598 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1599 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001600}
1601
Howard Hinnantc834c512011-11-29 18:15:50 +00001602template <class _Rp>
1603promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001604{
1605 if (__state_)
1606 {
1607 if (!__state_->__has_value() && __state_->use_count() > 1)
1608 __state_->set_exception(make_exception_ptr(
1609 future_error(make_error_code(future_errc::broken_promise))
1610 ));
1611 __state_->__release_shared();
1612 }
1613}
1614
Howard Hinnantc834c512011-11-29 18:15:50 +00001615template <class _Rp>
1616future<_Rp&>
1617promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001618{
1619 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001620 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001621 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001622}
1623
Howard Hinnantc834c512011-11-29 18:15:50 +00001624template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001625void
Howard Hinnantc834c512011-11-29 18:15:50 +00001626promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001627{
1628 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001629 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001630 __state_->set_value(__r);
1631}
1632
Howard Hinnantc834c512011-11-29 18:15:50 +00001633template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001634void
Howard Hinnantc834c512011-11-29 18:15:50 +00001635promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001636{
Marshall Clow2b36f572016-05-16 16:55:32 +00001637 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001638 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001639 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001640 __state_->set_exception(__p);
1641}
1642
Howard Hinnantc834c512011-11-29 18:15:50 +00001643template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001644void
Howard Hinnantc834c512011-11-29 18:15:50 +00001645promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001646{
1647 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001648 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001649 __state_->set_value_at_thread_exit(__r);
1650}
1651
Howard Hinnantc834c512011-11-29 18:15:50 +00001652template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001653void
Howard Hinnantc834c512011-11-29 18:15:50 +00001654promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001655{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001656 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001657 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001658 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001659 __state_->set_exception_at_thread_exit(__p);
1660}
1661
1662// promise<void>
1663
1664template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001665class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001666{
1667 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001668
Howard Hinnant684902d2010-09-22 14:16:26 +00001669 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001670 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001671
1672 template <class> friend class packaged_task;
1673
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001674public:
1675 promise();
1676 template <class _Allocator>
1677 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001678#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001680 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001681 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1682 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001683#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001684private:
1685 promise(const promise& __rhs);
1686public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001687#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001688 ~promise();
1689
1690 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001691#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001692 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001693 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001694 {
1695 promise(std::move(__rhs)).swap(*this);
1696 return *this;
1697 }
1698 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001699#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001700private:
1701 promise& operator=(const promise& __rhs);
1702public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001703#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001705 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001706
1707 // retrieving the result
1708 future<void> get_future();
1709
1710 // setting the result
1711 void set_value();
1712 void set_exception(exception_ptr __p);
1713
1714 // setting the result with deferred notification
1715 void set_value_at_thread_exit();
1716 void set_exception_at_thread_exit(exception_ptr __p);
1717};
1718
1719template <class _Alloc>
1720promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1721{
Eric Fiselier0d109272014-10-23 06:24:45 +00001722 typedef __assoc_sub_state_alloc<_Alloc> _State;
1723 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001724 typedef __allocator_destructor<_A2> _D2;
1725 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001726 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1727 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1728 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001729}
1730
Howard Hinnantc834c512011-11-29 18:15:50 +00001731template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001732inline _LIBCPP_INLINE_VISIBILITY
1733void
Howard Hinnant22448042012-07-21 17:46:55 +00001734swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001735{
1736 __x.swap(__y);
1737}
1738
Howard Hinnantc834c512011-11-29 18:15:50 +00001739template <class _Rp, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001740 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001741 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001742
Howard Hinnantccdd2032010-08-30 18:46:21 +00001743#ifndef _LIBCPP_HAS_NO_VARIADICS
1744
1745// packaged_task
1746
1747template<class _Fp> class __packaged_task_base;
1748
Howard Hinnantc834c512011-11-29 18:15:50 +00001749template<class _Rp, class ..._ArgTypes>
1750class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001751{
1752 __packaged_task_base(const __packaged_task_base&);
1753 __packaged_task_base& operator=(const __packaged_task_base&);
1754public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001755 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001756 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001757 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001758 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001759 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001760 virtual void destroy() = 0;
1761 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001762 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001763};
1764
1765template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1766
Howard Hinnantc834c512011-11-29 18:15:50 +00001767template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1768class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1769 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001770{
Howard Hinnantc834c512011-11-29 18:15:50 +00001771 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001772public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001773 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001774 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001776 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001778 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001779 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001781 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001782 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001783 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001784 virtual void destroy();
1785 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001786 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001787};
1788
Howard Hinnantc834c512011-11-29 18:15:50 +00001789template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001790void
Howard Hinnantc834c512011-11-29 18:15:50 +00001791__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001792 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001793{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001794 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001795}
1796
Howard Hinnantc834c512011-11-29 18:15:50 +00001797template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001798void
Howard Hinnantc834c512011-11-29 18:15:50 +00001799__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001800{
Howard Hinnantc834c512011-11-29 18:15:50 +00001801 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001802}
1803
Howard Hinnantc834c512011-11-29 18:15:50 +00001804template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001805void
Howard Hinnantc834c512011-11-29 18:15:50 +00001806__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001807{
Eric Fiselier0d109272014-10-23 06:24:45 +00001808 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1809 typedef allocator_traits<_Ap> _ATraits;
1810 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001811 _Ap __a(__f_.second());
1812 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001813 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001814}
1815
Howard Hinnantc834c512011-11-29 18:15:50 +00001816template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1817_Rp
1818__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001819{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001820 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001821}
1822
Howard Hinnant944510a2011-06-14 19:58:17 +00001823template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001824
Howard Hinnantc834c512011-11-29 18:15:50 +00001825template<class _Rp, class ..._ArgTypes>
1826class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001827{
Howard Hinnantc834c512011-11-29 18:15:50 +00001828 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001829 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001830 __base* __f_;
1831
1832public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001833 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001834
1835 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001837 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001838 template<class _Fp>
1839 __packaged_task_function(_Fp&& __f);
1840 template<class _Fp, class _Alloc>
1841 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001842
Howard Hinnant22448042012-07-21 17:46:55 +00001843 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1844 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001845
1846 __packaged_task_function(const __packaged_task_function&) = delete;
1847 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1848
1849 ~__packaged_task_function();
1850
Howard Hinnant22448042012-07-21 17:46:55 +00001851 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001852
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001853 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001854 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001855};
1856
Howard Hinnantc834c512011-11-29 18:15:50 +00001857template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001858__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001859{
1860 if (__f.__f_ == nullptr)
1861 __f_ = nullptr;
1862 else if (__f.__f_ == (__base*)&__f.__buf_)
1863 {
1864 __f_ = (__base*)&__buf_;
1865 __f.__f_->__move_to(__f_);
1866 }
1867 else
1868 {
1869 __f_ = __f.__f_;
1870 __f.__f_ = nullptr;
1871 }
1872}
1873
Howard Hinnantc834c512011-11-29 18:15:50 +00001874template<class _Rp, class ..._ArgTypes>
1875template <class _Fp>
1876__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001877 : __f_(nullptr)
1878{
Marshall Clow733d60e2014-04-07 13:32:26 +00001879 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001880 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001881 if (sizeof(_FF) <= sizeof(__buf_))
1882 {
1883 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001884 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001885 }
1886 else
1887 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001888 typedef allocator<_FF> _Ap;
1889 _Ap __a;
1890 typedef __allocator_destructor<_Ap> _Dp;
1891 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1892 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001893 __f_ = __hold.release();
1894 }
1895}
1896
Howard Hinnantc834c512011-11-29 18:15:50 +00001897template<class _Rp, class ..._ArgTypes>
1898template <class _Fp, class _Alloc>
1899__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1900 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001901 : __f_(nullptr)
1902{
Marshall Clow733d60e2014-04-07 13:32:26 +00001903 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001904 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001905 if (sizeof(_FF) <= sizeof(__buf_))
1906 {
1907 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001908 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001909 }
1910 else
1911 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001912 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001913 _Ap __a(__a0);
1914 typedef __allocator_destructor<_Ap> _Dp;
1915 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001916 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1917 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1918 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001919 }
1920}
1921
Howard Hinnantc834c512011-11-29 18:15:50 +00001922template<class _Rp, class ..._ArgTypes>
1923__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001924__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001925{
1926 if (__f_ == (__base*)&__buf_)
1927 __f_->destroy();
1928 else if (__f_)
1929 __f_->destroy_deallocate();
1930 __f_ = nullptr;
1931 if (__f.__f_ == nullptr)
1932 __f_ = nullptr;
1933 else if (__f.__f_ == (__base*)&__f.__buf_)
1934 {
1935 __f_ = (__base*)&__buf_;
1936 __f.__f_->__move_to(__f_);
1937 }
1938 else
1939 {
1940 __f_ = __f.__f_;
1941 __f.__f_ = nullptr;
1942 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001943 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001944}
1945
Howard Hinnantc834c512011-11-29 18:15:50 +00001946template<class _Rp, class ..._ArgTypes>
1947__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001948{
1949 if (__f_ == (__base*)&__buf_)
1950 __f_->destroy();
1951 else if (__f_)
1952 __f_->destroy_deallocate();
1953}
1954
Howard Hinnantc834c512011-11-29 18:15:50 +00001955template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001956void
Howard Hinnant22448042012-07-21 17:46:55 +00001957__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001958{
1959 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1960 {
1961 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1962 __base* __t = (__base*)&__tempbuf;
1963 __f_->__move_to(__t);
1964 __f_->destroy();
1965 __f_ = nullptr;
1966 __f.__f_->__move_to((__base*)&__buf_);
1967 __f.__f_->destroy();
1968 __f.__f_ = nullptr;
1969 __f_ = (__base*)&__buf_;
1970 __t->__move_to((__base*)&__f.__buf_);
1971 __t->destroy();
1972 __f.__f_ = (__base*)&__f.__buf_;
1973 }
1974 else if (__f_ == (__base*)&__buf_)
1975 {
1976 __f_->__move_to((__base*)&__f.__buf_);
1977 __f_->destroy();
1978 __f_ = __f.__f_;
1979 __f.__f_ = (__base*)&__f.__buf_;
1980 }
1981 else if (__f.__f_ == (__base*)&__f.__buf_)
1982 {
1983 __f.__f_->__move_to((__base*)&__buf_);
1984 __f.__f_->destroy();
1985 __f.__f_ = __f_;
1986 __f_ = (__base*)&__buf_;
1987 }
1988 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001989 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001990}
1991
Howard Hinnantc834c512011-11-29 18:15:50 +00001992template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001993inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001994_Rp
1995__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001996{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001997 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001998}
1999
Howard Hinnantc834c512011-11-29 18:15:50 +00002000template<class _Rp, class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002001class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002002{
2003public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002004 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002005
2006private:
2007 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2008 promise<result_type> __p_;
2009
2010public:
2011 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002012 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002013 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002014 template <class _Fp,
2015 class = typename enable_if
2016 <
2017 !is_same<
2018 typename decay<_Fp>::type,
2019 packaged_task
2020 >::value
2021 >::type
2022 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002023 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002024 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002025 template <class _Fp, class _Allocator,
2026 class = typename enable_if
2027 <
2028 !is_same<
2029 typename decay<_Fp>::type,
2030 packaged_task
2031 >::value
2032 >::type
2033 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002034 _LIBCPP_INLINE_VISIBILITY
Marshall Clowc317e022015-06-30 14:16:49 +00002035 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002036 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002037 __p_(allocator_arg, __a) {}
2038 // ~packaged_task() = default;
2039
2040 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002041 packaged_task(const packaged_task&) = delete;
2042 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002043
2044 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002045 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002046 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002047 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002049 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002050 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002051 __f_ = _VSTD::move(__other.__f_);
2052 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002053 return *this;
2054 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002055 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002056 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002057 {
2058 __f_.swap(__other.__f_);
2059 __p_.swap(__other.__p_);
2060 }
2061
Howard Hinnant684902d2010-09-22 14:16:26 +00002062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002063 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002064
2065 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002067 future<result_type> get_future() {return __p_.get_future();}
2068
2069 // execution
2070 void operator()(_ArgTypes... __args);
2071 void make_ready_at_thread_exit(_ArgTypes... __args);
2072
2073 void reset();
2074};
2075
Howard Hinnantc834c512011-11-29 18:15:50 +00002076template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002077void
Howard Hinnantc834c512011-11-29 18:15:50 +00002078packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002079{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002080 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002081 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002082 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002083 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002084#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002085 try
2086 {
2087#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002088 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002089#ifndef _LIBCPP_NO_EXCEPTIONS
2090 }
2091 catch (...)
2092 {
2093 __p_.set_exception(current_exception());
2094 }
2095#endif // _LIBCPP_NO_EXCEPTIONS
2096}
2097
Howard Hinnantc834c512011-11-29 18:15:50 +00002098template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002099void
Howard Hinnantc834c512011-11-29 18:15:50 +00002100packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002101{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002102 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002103 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002104 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002105 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002106#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002107 try
2108 {
2109#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002110 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002111#ifndef _LIBCPP_NO_EXCEPTIONS
2112 }
2113 catch (...)
2114 {
2115 __p_.set_exception_at_thread_exit(current_exception());
2116 }
2117#endif // _LIBCPP_NO_EXCEPTIONS
2118}
2119
Howard Hinnantc834c512011-11-29 18:15:50 +00002120template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002121void
Howard Hinnantc834c512011-11-29 18:15:50 +00002122packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002123{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002124 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002125 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002126 __p_ = promise<result_type>();
2127}
2128
2129template<class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002130class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002131{
2132public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002133 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002134
2135private:
2136 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2137 promise<result_type> __p_;
2138
2139public:
2140 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002142 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002143 template <class _Fp,
2144 class = typename enable_if
2145 <
2146 !is_same<
2147 typename decay<_Fp>::type,
2148 packaged_task
2149 >::value
2150 >::type
2151 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002152 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002153 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002154 template <class _Fp, class _Allocator,
2155 class = typename enable_if
2156 <
2157 !is_same<
2158 typename decay<_Fp>::type,
2159 packaged_task
2160 >::value
2161 >::type
2162 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002163 _LIBCPP_INLINE_VISIBILITY
Marshall Clow976e4822015-06-30 18:28:35 +00002164 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002165 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002166 __p_(allocator_arg, __a) {}
2167 // ~packaged_task() = default;
2168
2169 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002170 packaged_task(const packaged_task&) = delete;
2171 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002172
2173 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002174 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002175 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002176 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002177 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002178 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002179 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002180 __f_ = _VSTD::move(__other.__f_);
2181 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002182 return *this;
2183 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002184 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002185 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002186 {
2187 __f_.swap(__other.__f_);
2188 __p_.swap(__other.__p_);
2189 }
2190
Howard Hinnant684902d2010-09-22 14:16:26 +00002191 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002192 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002193
2194 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002195 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002196 future<result_type> get_future() {return __p_.get_future();}
2197
2198 // execution
2199 void operator()(_ArgTypes... __args);
2200 void make_ready_at_thread_exit(_ArgTypes... __args);
2201
2202 void reset();
2203};
2204
2205template<class ..._ArgTypes>
2206void
2207packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2208{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002209 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002210 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002211 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002212 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002213#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002214 try
2215 {
2216#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002217 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002218 __p_.set_value();
2219#ifndef _LIBCPP_NO_EXCEPTIONS
2220 }
2221 catch (...)
2222 {
2223 __p_.set_exception(current_exception());
2224 }
2225#endif // _LIBCPP_NO_EXCEPTIONS
2226}
2227
2228template<class ..._ArgTypes>
2229void
2230packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2231{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002232 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002233 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002234 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002235 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002236#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002237 try
2238 {
2239#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002240 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002241 __p_.set_value_at_thread_exit();
2242#ifndef _LIBCPP_NO_EXCEPTIONS
2243 }
2244 catch (...)
2245 {
2246 __p_.set_exception_at_thread_exit(current_exception());
2247 }
2248#endif // _LIBCPP_NO_EXCEPTIONS
2249}
2250
2251template<class ..._ArgTypes>
2252void
2253packaged_task<void(_ArgTypes...)>::reset()
2254{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002255 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002256 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002257 __p_ = promise<result_type>();
2258}
2259
2260template <class _Callable>
2261inline _LIBCPP_INLINE_VISIBILITY
2262void
Howard Hinnant22448042012-07-21 17:46:55 +00002263swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002264{
2265 __x.swap(__y);
2266}
2267
2268template <class _Callable, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002269struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00002270 : public true_type {};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002271
Howard Hinnantc834c512011-11-29 18:15:50 +00002272template <class _Rp, class _Fp>
2273future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002274#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002275__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002276#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002277__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002278#endif
2279{
Howard Hinnantc834c512011-11-29 18:15:50 +00002280 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2281 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2282 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002283}
2284
Howard Hinnantc834c512011-11-29 18:15:50 +00002285template <class _Rp, class _Fp>
2286future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002287#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002288__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002289#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002290__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002291#endif
2292{
Howard Hinnantc834c512011-11-29 18:15:50 +00002293 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2294 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2295 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2296 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002297}
2298
Howard Hinnantc834c512011-11-29 18:15:50 +00002299template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002300class __async_func
2301{
Howard Hinnantc834c512011-11-29 18:15:50 +00002302 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002303
2304public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002305 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002306
2307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002308 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002309 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002310
2311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002312 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002313
Howard Hinnantc834c512011-11-29 18:15:50 +00002314 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002315 {
2316 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2317 return __execute(_Index());
2318 }
2319private:
2320 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002321 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002322 __execute(__tuple_indices<_Indices...>)
2323 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002324 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002325 }
2326};
2327
Marshall Clowd56a5b62013-11-03 22:06:53 +00002328inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002329{ return (int(__policy) & int(__value)) != 0; }
2330
Howard Hinnantc834c512011-11-29 18:15:50 +00002331template <class _Fp, class... _Args>
2332future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2333async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002334{
Howard Hinnantc834c512011-11-29 18:15:50 +00002335 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2336 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002337
2338#ifndef _LIBCPP_NO_EXCEPTIONS
2339 try
2340 {
2341#endif
2342 if (__does_policy_contain(__policy, launch::async))
2343 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002344 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002345#ifndef _LIBCPP_NO_EXCEPTIONS
2346 }
2347 catch ( ... ) { if (__policy == launch::async) throw ; }
2348#endif
2349
2350 if (__does_policy_contain(__policy, launch::deferred))
2351 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002352 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002353 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002354}
2355
Howard Hinnantc834c512011-11-29 18:15:50 +00002356template <class _Fp, class... _Args>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002357inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002358future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2359async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002360{
Howard Hinnantc834c512011-11-29 18:15:50 +00002361 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002362 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002363}
2364
2365#endif // _LIBCPP_HAS_NO_VARIADICS
2366
Howard Hinnante6a10852010-09-03 21:46:37 +00002367// shared_future
2368
Howard Hinnantc834c512011-11-29 18:15:50 +00002369template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002370class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002371{
Howard Hinnantc834c512011-11-29 18:15:50 +00002372 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002373
2374public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002376 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002377 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002378 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002379 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002380#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002381 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002382 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002383 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002385 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002386 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002387#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002388 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002389 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant74279a52010-09-04 23:28:19 +00002390#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002392 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002393 {
2394 shared_future(std::move(__rhs)).swap(*this);
2395 return *this;
2396 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002397#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002398
2399 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002401 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002402
Howard Hinnant684902d2010-09-22 14:16:26 +00002403 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002404 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002405
2406 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002408 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002409
Howard Hinnant684902d2010-09-22 14:16:26 +00002410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002411 void wait() const {__state_->wait();}
2412 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002414 future_status
2415 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2416 {return __state_->wait_for(__rel_time);}
2417 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002418 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002419 future_status
2420 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2421 {return __state_->wait_until(__abs_time);}
2422};
2423
Howard Hinnantc834c512011-11-29 18:15:50 +00002424template <class _Rp>
2425shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002426{
2427 if (__state_)
2428 __state_->__release_shared();
2429}
2430
Howard Hinnantc834c512011-11-29 18:15:50 +00002431template <class _Rp>
2432shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002433shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002434{
2435 if (__rhs.__state_)
2436 __rhs.__state_->__add_shared();
2437 if (__state_)
2438 __state_->__release_shared();
2439 __state_ = __rhs.__state_;
2440 return *this;
2441}
2442
Howard Hinnantc834c512011-11-29 18:15:50 +00002443template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002444class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002445{
Howard Hinnantc834c512011-11-29 18:15:50 +00002446 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002447
2448public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002449 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002450 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002451 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002452 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2453 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002454#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002456 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002457 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002459 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002460 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002461#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002462 ~shared_future();
2463 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002464#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002466 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002467 {
2468 shared_future(std::move(__rhs)).swap(*this);
2469 return *this;
2470 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002471#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002472
2473 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002475 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002476
Howard Hinnant684902d2010-09-22 14:16:26 +00002477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002478 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002479
2480 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002482 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002483
Howard Hinnant684902d2010-09-22 14:16:26 +00002484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002485 void wait() const {__state_->wait();}
2486 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002487 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002488 future_status
2489 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2490 {return __state_->wait_for(__rel_time);}
2491 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002493 future_status
2494 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2495 {return __state_->wait_until(__abs_time);}
2496};
2497
Howard Hinnantc834c512011-11-29 18:15:50 +00002498template <class _Rp>
2499shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002500{
2501 if (__state_)
2502 __state_->__release_shared();
2503}
2504
Howard Hinnantc834c512011-11-29 18:15:50 +00002505template <class _Rp>
2506shared_future<_Rp&>&
2507shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002508{
2509 if (__rhs.__state_)
2510 __rhs.__state_->__add_shared();
2511 if (__state_)
2512 __state_->__release_shared();
2513 __state_ = __rhs.__state_;
2514 return *this;
2515}
2516
2517template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00002518class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002519{
2520 __assoc_sub_state* __state_;
2521
2522public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002523 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002524 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002525 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002526 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2527 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002528#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002529 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002530 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002531 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002533 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002534 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002535#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002536 ~shared_future();
2537 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002538#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002540 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002541 {
2542 shared_future(std::move(__rhs)).swap(*this);
2543 return *this;
2544 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002545#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002546
2547 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002549 void get() const {__state_->copy();}
2550
Howard Hinnant684902d2010-09-22 14:16:26 +00002551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002552 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002553
2554 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002556 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002557
Howard Hinnant684902d2010-09-22 14:16:26 +00002558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002559 void wait() const {__state_->wait();}
2560 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002562 future_status
2563 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2564 {return __state_->wait_for(__rel_time);}
2565 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002567 future_status
2568 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2569 {return __state_->wait_until(__abs_time);}
2570};
2571
Howard Hinnantc834c512011-11-29 18:15:50 +00002572template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002573inline _LIBCPP_INLINE_VISIBILITY
2574void
Howard Hinnant22448042012-07-21 17:46:55 +00002575swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002576{
2577 __x.swap(__y);
2578}
2579
Howard Hinnantc834c512011-11-29 18:15:50 +00002580template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002581inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002582shared_future<_Rp>
2583future<_Rp>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002584{
Howard Hinnantc834c512011-11-29 18:15:50 +00002585 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002586}
2587
Howard Hinnantc834c512011-11-29 18:15:50 +00002588template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002589inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002590shared_future<_Rp&>
2591future<_Rp&>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002592{
Howard Hinnantc834c512011-11-29 18:15:50 +00002593 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002594}
2595
Howard Hinnante65e8e32010-12-02 16:45:21 +00002596#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2597
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002598inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002599shared_future<void>
2600future<void>::share()
2601{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002602 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002603}
2604
Howard Hinnante65e8e32010-12-02 16:45:21 +00002605#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2606
Howard Hinnantc51e1022010-05-11 19:42:16 +00002607_LIBCPP_END_NAMESPACE_STD
2608
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002609#endif // !_LIBCPP_HAS_NO_THREADS
2610
Howard Hinnantc51e1022010-05-11 19:42:16 +00002611#endif // _LIBCPP_FUTURE