blob: 656f9c7466157255ce4a0c24475b1e9a6cf8ee0c [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
Marshall Clow8fea1612016-08-25 15:09:01 +0000523 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000524#endif
525}
526
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000527class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000528 : public __shared_count
529{
530protected:
531 exception_ptr __exception_;
532 mutable mutex __mut_;
533 mutable condition_variable __cv_;
534 unsigned __state_;
535
Howard Hinnant719bda32011-05-28 14:41:13 +0000536 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000537 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000538public:
539 enum
540 {
541 __constructed = 1,
542 __future_attached = 2,
543 ready = 4,
544 deferred = 8
545 };
546
Howard Hinnant684902d2010-09-22 14:16:26 +0000547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000548 __assoc_sub_state() : __state_(0) {}
549
Howard Hinnant684902d2010-09-22 14:16:26 +0000550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000551 bool __has_value() const
552 {return (__state_ & __constructed) || (__exception_ != nullptr);}
553
Howard Hinnant684902d2010-09-22 14:16:26 +0000554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante667ecc2013-01-14 20:01:24 +0000555 void __set_future_attached()
556 {
557 lock_guard<mutex> __lk(__mut_);
558 __state_ |= __future_attached;
559 }
Howard Hinnant684902d2010-09-22 14:16:26 +0000560 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000561 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000562
Howard Hinnant684902d2010-09-22 14:16:26 +0000563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000564 void __set_deferred() {__state_ |= deferred;}
565
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000566 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000567 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000568 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000569
570 void set_value();
571 void set_value_at_thread_exit();
572
573 void set_exception(exception_ptr __p);
574 void set_exception_at_thread_exit(exception_ptr __p);
575
576 void copy();
577
Howard Hinnantccdd2032010-08-30 18:46:21 +0000578 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000579 template <class _Rep, class _Period>
580 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000581 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000582 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
583 template <class _Clock, class _Duration>
584 future_status
585 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000586
587 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000588};
589
Howard Hinnantf4712b92010-08-28 21:01:06 +0000590template <class _Clock, class _Duration>
591future_status
592__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
593{
594 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000595 if (__state_ & deferred)
596 return future_status::deferred;
597 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000598 __cv_.wait_until(__lk, __abs_time);
599 if (__state_ & ready)
600 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000601 return future_status::timeout;
602}
603
604template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000605inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000606future_status
607__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
608{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000609 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000610}
611
Howard Hinnantc834c512011-11-29 18:15:50 +0000612template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000613class __assoc_state
614 : public __assoc_sub_state
615{
616 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000617 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000618protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000619 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620
Howard Hinnant719bda32011-05-28 14:41:13 +0000621 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000622public:
623
624 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000625#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000626 void set_value(_Arg&& __arg);
627#else
628 void set_value(_Arg& __arg);
629#endif
630
631 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000632#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000633 void set_value_at_thread_exit(_Arg&& __arg);
634#else
635 void set_value_at_thread_exit(_Arg& __arg);
636#endif
637
Howard Hinnantc834c512011-11-29 18:15:50 +0000638 _Rp move();
639 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000640};
641
Howard Hinnantc834c512011-11-29 18:15:50 +0000642template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000643void
Howard Hinnantc834c512011-11-29 18:15:50 +0000644__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000645{
646 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000647 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000648 delete this;
649}
650
Howard Hinnantc834c512011-11-29 18:15:50 +0000651template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000652template <class _Arg>
653void
Howard Hinnant74279a52010-09-04 23:28:19 +0000654#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000655__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000656#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000657__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000658#endif
659{
660 unique_lock<mutex> __lk(this->__mut_);
661 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000662 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000663 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000664 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000665 __cv_.notify_all();
666}
667
Howard Hinnantc834c512011-11-29 18:15:50 +0000668template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000669template <class _Arg>
670void
Howard Hinnant74279a52010-09-04 23:28:19 +0000671#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000672__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000673#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000674__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675#endif
676{
677 unique_lock<mutex> __lk(this->__mut_);
678 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000679 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000680 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000681 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000682 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000683}
684
Howard Hinnantc834c512011-11-29 18:15:50 +0000685template <class _Rp>
686_Rp
687__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000688{
689 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000690 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000691 if (this->__exception_ != nullptr)
692 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000693 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000694}
695
Howard Hinnantc834c512011-11-29 18:15:50 +0000696template <class _Rp>
697typename add_lvalue_reference<_Rp>::type
698__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000699{
700 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000701 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000702 if (this->__exception_ != nullptr)
703 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000704 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000705}
706
Howard Hinnantc834c512011-11-29 18:15:50 +0000707template <class _Rp>
708class __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000709 : public __assoc_sub_state
710{
711 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000712 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000713protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000714 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715
Howard Hinnant719bda32011-05-28 14:41:13 +0000716 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000717public:
718
Howard Hinnantc834c512011-11-29 18:15:50 +0000719 void set_value(_Rp& __arg);
720 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000721
Howard Hinnantc834c512011-11-29 18:15:50 +0000722 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000723};
724
Howard Hinnantc834c512011-11-29 18:15:50 +0000725template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000726void
Howard Hinnantc834c512011-11-29 18:15:50 +0000727__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728{
729 delete this;
730}
731
Howard Hinnantc834c512011-11-29 18:15:50 +0000732template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000733void
Howard Hinnantc834c512011-11-29 18:15:50 +0000734__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000735{
736 unique_lock<mutex> __lk(this->__mut_);
737 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000738 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000739 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000740 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000741 __cv_.notify_all();
742}
743
Howard Hinnantc834c512011-11-29 18:15:50 +0000744template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000745void
Howard Hinnantc834c512011-11-29 18:15:50 +0000746__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000747{
748 unique_lock<mutex> __lk(this->__mut_);
749 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000750 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000751 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000752 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000753 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000754}
755
Howard Hinnantc834c512011-11-29 18:15:50 +0000756template <class _Rp>
757_Rp&
758__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000759{
760 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000761 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000762 if (this->__exception_ != nullptr)
763 rethrow_exception(this->__exception_);
764 return *__value_;
765}
766
Howard Hinnantc834c512011-11-29 18:15:50 +0000767template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000768class __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000769 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000770{
Howard Hinnantc834c512011-11-29 18:15:50 +0000771 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000772 _Alloc __alloc_;
773
Howard Hinnant719bda32011-05-28 14:41:13 +0000774 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000775public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000777 explicit __assoc_state_alloc(const _Alloc& __a)
778 : __alloc_(__a) {}
779};
780
Howard Hinnantc834c512011-11-29 18:15:50 +0000781template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000782void
Howard Hinnantc834c512011-11-29 18:15:50 +0000783__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000784{
785 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000786 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000787 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
788 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000789 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000790 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000791 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000792 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000793}
794
Howard Hinnantc834c512011-11-29 18:15:50 +0000795template <class _Rp, class _Alloc>
796class __assoc_state_alloc<_Rp&, _Alloc>
797 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000798{
Howard Hinnantc834c512011-11-29 18:15:50 +0000799 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000800 _Alloc __alloc_;
801
Howard Hinnant719bda32011-05-28 14:41:13 +0000802 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000803public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000804 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000805 explicit __assoc_state_alloc(const _Alloc& __a)
806 : __alloc_(__a) {}
807};
808
Howard Hinnantc834c512011-11-29 18:15:50 +0000809template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000810void
Howard Hinnantc834c512011-11-29 18:15:50 +0000811__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000812{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000813 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
814 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000815 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000816 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000817 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000818 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000819}
820
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000821template <class _Alloc>
822class __assoc_sub_state_alloc
823 : public __assoc_sub_state
824{
825 typedef __assoc_sub_state base;
826 _Alloc __alloc_;
827
Howard Hinnant719bda32011-05-28 14:41:13 +0000828 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000829public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000830 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000831 explicit __assoc_sub_state_alloc(const _Alloc& __a)
832 : __alloc_(__a) {}
833};
834
835template <class _Alloc>
836void
Howard Hinnant719bda32011-05-28 14:41:13 +0000837__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000838{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000839 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
840 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000841 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000842 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000843 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000844 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000845}
846
Howard Hinnantc834c512011-11-29 18:15:50 +0000847template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000848class __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000849 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000850{
Howard Hinnantc834c512011-11-29 18:15:50 +0000851 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000852
Howard Hinnantc834c512011-11-29 18:15:50 +0000853 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000854
855public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000856#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000857 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000858 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000859#endif
860
861 virtual void __execute();
862};
863
Howard Hinnant74279a52010-09-04 23:28:19 +0000864#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000865
Howard Hinnantc834c512011-11-29 18:15:50 +0000866template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000867inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000868__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
869 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000870{
871 this->__set_deferred();
872}
873
Howard Hinnant74279a52010-09-04 23:28:19 +0000874#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000875
Howard Hinnantc834c512011-11-29 18:15:50 +0000876template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000877void
Howard Hinnantc834c512011-11-29 18:15:50 +0000878__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000879{
880#ifndef _LIBCPP_NO_EXCEPTIONS
881 try
882 {
883#endif // _LIBCPP_NO_EXCEPTIONS
884 this->set_value(__func_());
885#ifndef _LIBCPP_NO_EXCEPTIONS
886 }
887 catch (...)
888 {
889 this->set_exception(current_exception());
890 }
891#endif // _LIBCPP_NO_EXCEPTIONS
892}
893
Howard Hinnantc834c512011-11-29 18:15:50 +0000894template <class _Fp>
895class __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000896 : public __assoc_sub_state
897{
898 typedef __assoc_sub_state base;
899
Howard Hinnantc834c512011-11-29 18:15:50 +0000900 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000901
902public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000903#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000904 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000905 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000906#endif
907
908 virtual void __execute();
909};
910
Howard Hinnant74279a52010-09-04 23:28:19 +0000911#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000912
Howard Hinnantc834c512011-11-29 18:15:50 +0000913template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000914inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000915__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
916 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000917{
918 this->__set_deferred();
919}
920
Howard Hinnant74279a52010-09-04 23:28:19 +0000921#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000922
Howard Hinnantc834c512011-11-29 18:15:50 +0000923template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000924void
Howard Hinnantc834c512011-11-29 18:15:50 +0000925__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000926{
927#ifndef _LIBCPP_NO_EXCEPTIONS
928 try
929 {
930#endif // _LIBCPP_NO_EXCEPTIONS
931 __func_();
932 this->set_value();
933#ifndef _LIBCPP_NO_EXCEPTIONS
934 }
935 catch (...)
936 {
937 this->set_exception(current_exception());
938 }
939#endif // _LIBCPP_NO_EXCEPTIONS
940}
941
Howard Hinnantc834c512011-11-29 18:15:50 +0000942template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000943class __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000944 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000945{
Howard Hinnantc834c512011-11-29 18:15:50 +0000946 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000947
Howard Hinnantc834c512011-11-29 18:15:50 +0000948 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000949
Howard Hinnant719bda32011-05-28 14:41:13 +0000950 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000951public:
952#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000953 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000954 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000955#endif
956
957 virtual void __execute();
958};
959
960#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
961
Howard Hinnantc834c512011-11-29 18:15:50 +0000962template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000963inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000964__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
965 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000966{
967}
968
969#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
970
Howard Hinnantc834c512011-11-29 18:15:50 +0000971template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000972void
Howard Hinnantc834c512011-11-29 18:15:50 +0000973__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000974{
975#ifndef _LIBCPP_NO_EXCEPTIONS
976 try
977 {
978#endif // _LIBCPP_NO_EXCEPTIONS
979 this->set_value(__func_());
980#ifndef _LIBCPP_NO_EXCEPTIONS
981 }
982 catch (...)
983 {
984 this->set_exception(current_exception());
985 }
986#endif // _LIBCPP_NO_EXCEPTIONS
987}
988
Howard Hinnantc834c512011-11-29 18:15:50 +0000989template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000990void
Howard Hinnantc834c512011-11-29 18:15:50 +0000991__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000992{
993 this->wait();
994 base::__on_zero_shared();
995}
996
Howard Hinnantc834c512011-11-29 18:15:50 +0000997template <class _Fp>
998class __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000999 : public __assoc_sub_state
1000{
1001 typedef __assoc_sub_state base;
1002
Howard Hinnantc834c512011-11-29 18:15:50 +00001003 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001004
Howard Hinnant719bda32011-05-28 14:41:13 +00001005 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001006public:
1007#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001008 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001009 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001010#endif
1011
1012 virtual void __execute();
1013};
1014
1015#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1016
Howard Hinnantc834c512011-11-29 18:15:50 +00001017template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001018inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001019__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1020 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001021{
1022}
1023
1024#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1025
Howard Hinnantc834c512011-11-29 18:15:50 +00001026template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001027void
Howard Hinnantc834c512011-11-29 18:15:50 +00001028__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001029{
1030#ifndef _LIBCPP_NO_EXCEPTIONS
1031 try
1032 {
1033#endif // _LIBCPP_NO_EXCEPTIONS
1034 __func_();
1035 this->set_value();
1036#ifndef _LIBCPP_NO_EXCEPTIONS
1037 }
1038 catch (...)
1039 {
1040 this->set_exception(current_exception());
1041 }
1042#endif // _LIBCPP_NO_EXCEPTIONS
1043}
1044
Howard Hinnantc834c512011-11-29 18:15:50 +00001045template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001046void
Howard Hinnantc834c512011-11-29 18:15:50 +00001047__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001048{
1049 this->wait();
1050 base::__on_zero_shared();
1051}
1052
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001053template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1054template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001055
1056// future
1057
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001058template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001059
Howard Hinnantc834c512011-11-29 18:15:50 +00001060template <class _Rp, class _Fp>
1061future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001062#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001063__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001064#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001065__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001066#endif
1067
Howard Hinnantc834c512011-11-29 18:15:50 +00001068template <class _Rp, class _Fp>
1069future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001070#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001071__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001072#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001073__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001074#endif
1075
Howard Hinnantc834c512011-11-29 18:15:50 +00001076template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001077class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001078{
Howard Hinnantc834c512011-11-29 18:15:50 +00001079 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001080
Howard Hinnantc834c512011-11-29 18:15:50 +00001081 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001082
1083 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001084 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001085
Howard Hinnant74279a52010-09-04 23:28:19 +00001086#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001087 template <class _R1, class _Fp>
1088 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1089 template <class _R1, class _Fp>
1090 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001091#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001092 template <class _R1, class _Fp>
1093 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1094 template <class _R1, class _Fp>
1095 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001096#endif
1097
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001098public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001099 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001100 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001101#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001102 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001103 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001104 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1105 future(const future&) = delete;
1106 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001107 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001108 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001109 {
1110 future(std::move(__rhs)).swap(*this);
1111 return *this;
1112 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001113#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001114private:
1115 future(const future&);
1116 future& operator=(const future&);
1117public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001118#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001119 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001120 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001121 shared_future<_Rp> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001122
1123 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001124 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001125
Howard Hinnant684902d2010-09-22 14:16:26 +00001126 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001127 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001128
1129 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001130 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001131 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001132
Howard Hinnant684902d2010-09-22 14:16:26 +00001133 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001134 void wait() const {__state_->wait();}
1135 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001137 future_status
1138 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1139 {return __state_->wait_for(__rel_time);}
1140 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001142 future_status
1143 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1144 {return __state_->wait_until(__abs_time);}
1145};
1146
Howard Hinnantc834c512011-11-29 18:15:50 +00001147template <class _Rp>
1148future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001149 : __state_(__state)
1150{
1151 if (__state_->__has_future_attached())
Eric Fiselier43641592015-10-02 21:25:15 +00001152 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001153 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001154 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001155}
1156
Howard Hinnantccdd2032010-08-30 18:46:21 +00001157struct __release_shared_count
1158{
1159 void operator()(__shared_count* p) {p->__release_shared();}
1160};
1161
Howard Hinnantc834c512011-11-29 18:15:50 +00001162template <class _Rp>
1163future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001164{
1165 if (__state_)
1166 __state_->__release_shared();
1167}
1168
Howard Hinnantc834c512011-11-29 18:15:50 +00001169template <class _Rp>
1170_Rp
1171future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001172{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001173 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001174 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001175 __state_ = nullptr;
1176 return __s->move();
1177}
1178
Howard Hinnantc834c512011-11-29 18:15:50 +00001179template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001180class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001181{
Howard Hinnantc834c512011-11-29 18:15:50 +00001182 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001183
Howard Hinnantc834c512011-11-29 18:15:50 +00001184 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001185
1186 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001187 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001188
Howard Hinnant74279a52010-09-04 23:28:19 +00001189#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001190 template <class _R1, class _Fp>
1191 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1192 template <class _R1, class _Fp>
1193 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001194#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001195 template <class _R1, class _Fp>
1196 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1197 template <class _R1, class _Fp>
1198 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001199#endif
1200
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001201public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001202 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001203 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001204#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001206 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001207 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1208 future(const future&) = delete;
1209 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001210 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001211 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001212 {
1213 future(std::move(__rhs)).swap(*this);
1214 return *this;
1215 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001216#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001217private:
1218 future(const future&);
1219 future& operator=(const future&);
1220public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001221#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001222 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001223 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001224 shared_future<_Rp&> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001225
1226 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001227 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001228
Howard Hinnant684902d2010-09-22 14:16:26 +00001229 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001230 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001231
1232 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001234 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001235
Howard Hinnant684902d2010-09-22 14:16:26 +00001236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001237 void wait() const {__state_->wait();}
1238 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001240 future_status
1241 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1242 {return __state_->wait_for(__rel_time);}
1243 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001245 future_status
1246 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1247 {return __state_->wait_until(__abs_time);}
1248};
1249
Howard Hinnantc834c512011-11-29 18:15:50 +00001250template <class _Rp>
1251future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001252 : __state_(__state)
1253{
1254 if (__state_->__has_future_attached())
Eric Fiselier43641592015-10-02 21:25:15 +00001255 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001256 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001257 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001258}
1259
Howard Hinnantc834c512011-11-29 18:15:50 +00001260template <class _Rp>
1261future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001262{
1263 if (__state_)
1264 __state_->__release_shared();
1265}
1266
Howard Hinnantc834c512011-11-29 18:15:50 +00001267template <class _Rp>
1268_Rp&
1269future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001270{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001271 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001272 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001273 __state_ = nullptr;
1274 return __s->copy();
1275}
1276
1277template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001278class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001279{
1280 __assoc_sub_state* __state_;
1281
1282 explicit future(__assoc_sub_state* __state);
1283
1284 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001285 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001286
Howard Hinnant74279a52010-09-04 23:28:19 +00001287#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001288 template <class _R1, class _Fp>
1289 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1290 template <class _R1, class _Fp>
1291 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001292#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001293 template <class _R1, class _Fp>
1294 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1295 template <class _R1, class _Fp>
1296 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001297#endif
1298
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001299public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001301 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001302#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001303 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001304 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001305 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1306 future(const future&) = delete;
1307 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001309 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001310 {
1311 future(std::move(__rhs)).swap(*this);
1312 return *this;
1313 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001314#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001315private:
1316 future(const future&);
1317 future& operator=(const future&);
1318public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001319#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001320 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001322 shared_future<void> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001323
1324 // retrieving the value
1325 void get();
1326
Howard Hinnant684902d2010-09-22 14:16:26 +00001327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001328 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001329
1330 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001331 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001332 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001333
Howard Hinnant684902d2010-09-22 14:16:26 +00001334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001335 void wait() const {__state_->wait();}
1336 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001337 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001338 future_status
1339 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1340 {return __state_->wait_for(__rel_time);}
1341 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001342 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001343 future_status
1344 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1345 {return __state_->wait_until(__abs_time);}
1346};
1347
Howard Hinnantc834c512011-11-29 18:15:50 +00001348template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001349inline _LIBCPP_INLINE_VISIBILITY
1350void
Howard Hinnant22448042012-07-21 17:46:55 +00001351swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001352{
1353 __x.swap(__y);
1354}
1355
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001356// promise<R>
1357
Howard Hinnant944510a2011-06-14 19:58:17 +00001358template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001359
Howard Hinnantc834c512011-11-29 18:15:50 +00001360template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001361class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001362{
Howard Hinnantc834c512011-11-29 18:15:50 +00001363 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001364
Howard Hinnant684902d2010-09-22 14:16:26 +00001365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001366 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001367
1368 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001369public:
1370 promise();
1371 template <class _Alloc>
1372 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001373#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001375 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001376 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1377 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001378#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001379private:
1380 promise(const promise& __rhs);
1381public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001382#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001383 ~promise();
1384
1385 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001386#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001388 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001389 {
1390 promise(std::move(__rhs)).swap(*this);
1391 return *this;
1392 }
1393 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001394#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001395private:
1396 promise& operator=(const promise& __rhs);
1397public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001398#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001400 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001401
1402 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001403 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001404
1405 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001406 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001407#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001408 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001409#endif
1410 void set_exception(exception_ptr __p);
1411
1412 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001413 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001414#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001415 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001416#endif
1417 void set_exception_at_thread_exit(exception_ptr __p);
1418};
1419
Howard Hinnantc834c512011-11-29 18:15:50 +00001420template <class _Rp>
1421promise<_Rp>::promise()
1422 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001423{
1424}
1425
Howard Hinnantc834c512011-11-29 18:15:50 +00001426template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001427template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001428promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001429{
Eric Fiselier0d109272014-10-23 06:24:45 +00001430 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1431 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001432 typedef __allocator_destructor<_A2> _D2;
1433 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001434 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1435 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1436 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001437}
1438
Howard Hinnantc834c512011-11-29 18:15:50 +00001439template <class _Rp>
1440promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001441{
1442 if (__state_)
1443 {
1444 if (!__state_->__has_value() && __state_->use_count() > 1)
1445 __state_->set_exception(make_exception_ptr(
1446 future_error(make_error_code(future_errc::broken_promise))
1447 ));
1448 __state_->__release_shared();
1449 }
1450}
1451
Howard Hinnantc834c512011-11-29 18:15:50 +00001452template <class _Rp>
1453future<_Rp>
1454promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001455{
1456 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001457 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001458 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001459}
1460
Howard Hinnantc834c512011-11-29 18:15:50 +00001461template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001462void
Howard Hinnantc834c512011-11-29 18:15:50 +00001463promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001464{
1465 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001466 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001467 __state_->set_value(__r);
1468}
1469
Howard Hinnant74279a52010-09-04 23:28:19 +00001470#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001471
Howard Hinnantc834c512011-11-29 18:15:50 +00001472template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001473void
Howard Hinnantc834c512011-11-29 18:15:50 +00001474promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001475{
1476 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001477 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001478 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001479}
1480
Howard Hinnant74279a52010-09-04 23:28:19 +00001481#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001482
Howard Hinnantc834c512011-11-29 18:15:50 +00001483template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001484void
Howard Hinnantc834c512011-11-29 18:15:50 +00001485promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001486{
Marshall Clow2b36f572016-05-16 16:55:32 +00001487 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001488 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001489 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001490 __state_->set_exception(__p);
1491}
1492
Howard Hinnantc834c512011-11-29 18:15:50 +00001493template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001494void
Howard Hinnantc834c512011-11-29 18:15:50 +00001495promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001496{
1497 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001498 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001499 __state_->set_value_at_thread_exit(__r);
1500}
1501
Howard Hinnant74279a52010-09-04 23:28:19 +00001502#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001503
Howard Hinnantc834c512011-11-29 18:15:50 +00001504template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001505void
Howard Hinnantc834c512011-11-29 18:15:50 +00001506promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001507{
1508 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001509 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001510 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001511}
1512
Howard Hinnant74279a52010-09-04 23:28:19 +00001513#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001514
Howard Hinnantc834c512011-11-29 18:15:50 +00001515template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001516void
Howard Hinnantc834c512011-11-29 18:15:50 +00001517promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001518{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001519 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001520 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001521 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001522 __state_->set_exception_at_thread_exit(__p);
1523}
1524
1525// promise<R&>
1526
Howard Hinnantc834c512011-11-29 18:15:50 +00001527template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001528class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001529{
Howard Hinnantc834c512011-11-29 18:15:50 +00001530 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001531
Howard Hinnant684902d2010-09-22 14:16:26 +00001532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001533 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001534
1535 template <class> friend class packaged_task;
1536
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001537public:
1538 promise();
1539 template <class _Allocator>
1540 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001541#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001543 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001544 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1545 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001546#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001547private:
1548 promise(const promise& __rhs);
1549public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001550#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001551 ~promise();
1552
1553 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001554#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001556 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001557 {
1558 promise(std::move(__rhs)).swap(*this);
1559 return *this;
1560 }
1561 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001562#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001563private:
1564 promise& operator=(const promise& __rhs);
1565public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001566#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001568 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001569
1570 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001571 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001572
1573 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001574 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001575 void set_exception(exception_ptr __p);
1576
1577 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001578 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001579 void set_exception_at_thread_exit(exception_ptr __p);
1580};
1581
Howard Hinnantc834c512011-11-29 18:15:50 +00001582template <class _Rp>
1583promise<_Rp&>::promise()
1584 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001585{
1586}
1587
Howard Hinnantc834c512011-11-29 18:15:50 +00001588template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001589template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001590promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001591{
Eric Fiselier0d109272014-10-23 06:24:45 +00001592 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1593 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001594 typedef __allocator_destructor<_A2> _D2;
1595 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001596 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1597 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1598 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001599}
1600
Howard Hinnantc834c512011-11-29 18:15:50 +00001601template <class _Rp>
1602promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001603{
1604 if (__state_)
1605 {
1606 if (!__state_->__has_value() && __state_->use_count() > 1)
1607 __state_->set_exception(make_exception_ptr(
1608 future_error(make_error_code(future_errc::broken_promise))
1609 ));
1610 __state_->__release_shared();
1611 }
1612}
1613
Howard Hinnantc834c512011-11-29 18:15:50 +00001614template <class _Rp>
1615future<_Rp&>
1616promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001617{
1618 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001619 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001620 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001621}
1622
Howard Hinnantc834c512011-11-29 18:15:50 +00001623template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001624void
Howard Hinnantc834c512011-11-29 18:15:50 +00001625promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001626{
1627 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001628 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001629 __state_->set_value(__r);
1630}
1631
Howard Hinnantc834c512011-11-29 18:15:50 +00001632template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001633void
Howard Hinnantc834c512011-11-29 18:15:50 +00001634promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001635{
Marshall Clow2b36f572016-05-16 16:55:32 +00001636 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001637 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001638 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001639 __state_->set_exception(__p);
1640}
1641
Howard Hinnantc834c512011-11-29 18:15:50 +00001642template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001643void
Howard Hinnantc834c512011-11-29 18:15:50 +00001644promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001645{
1646 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001647 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001648 __state_->set_value_at_thread_exit(__r);
1649}
1650
Howard Hinnantc834c512011-11-29 18:15:50 +00001651template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001652void
Howard Hinnantc834c512011-11-29 18:15:50 +00001653promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001654{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001655 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001656 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001657 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001658 __state_->set_exception_at_thread_exit(__p);
1659}
1660
1661// promise<void>
1662
1663template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001664class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001665{
1666 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001667
Howard Hinnant684902d2010-09-22 14:16:26 +00001668 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001669 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001670
1671 template <class> friend class packaged_task;
1672
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001673public:
1674 promise();
1675 template <class _Allocator>
1676 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001677#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001678 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001679 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001680 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1681 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001682#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001683private:
1684 promise(const promise& __rhs);
1685public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001686#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001687 ~promise();
1688
1689 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001690#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001691 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001692 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001693 {
1694 promise(std::move(__rhs)).swap(*this);
1695 return *this;
1696 }
1697 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001698#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001699private:
1700 promise& operator=(const promise& __rhs);
1701public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001702#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001704 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001705
1706 // retrieving the result
1707 future<void> get_future();
1708
1709 // setting the result
1710 void set_value();
1711 void set_exception(exception_ptr __p);
1712
1713 // setting the result with deferred notification
1714 void set_value_at_thread_exit();
1715 void set_exception_at_thread_exit(exception_ptr __p);
1716};
1717
1718template <class _Alloc>
1719promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1720{
Eric Fiselier0d109272014-10-23 06:24:45 +00001721 typedef __assoc_sub_state_alloc<_Alloc> _State;
1722 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001723 typedef __allocator_destructor<_A2> _D2;
1724 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001725 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1726 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1727 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001728}
1729
Howard Hinnantc834c512011-11-29 18:15:50 +00001730template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001731inline _LIBCPP_INLINE_VISIBILITY
1732void
Howard Hinnant22448042012-07-21 17:46:55 +00001733swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001734{
1735 __x.swap(__y);
1736}
1737
Howard Hinnantc834c512011-11-29 18:15:50 +00001738template <class _Rp, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001739 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001740 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001741
Howard Hinnantccdd2032010-08-30 18:46:21 +00001742#ifndef _LIBCPP_HAS_NO_VARIADICS
1743
1744// packaged_task
1745
1746template<class _Fp> class __packaged_task_base;
1747
Howard Hinnantc834c512011-11-29 18:15:50 +00001748template<class _Rp, class ..._ArgTypes>
1749class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001750{
1751 __packaged_task_base(const __packaged_task_base&);
1752 __packaged_task_base& operator=(const __packaged_task_base&);
1753public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001755 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001757 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001758 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001759 virtual void destroy() = 0;
1760 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001761 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001762};
1763
1764template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1765
Howard Hinnantc834c512011-11-29 18:15:50 +00001766template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1767class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1768 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001769{
Howard Hinnantc834c512011-11-29 18:15:50 +00001770 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001771public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001773 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001775 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001777 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001778 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001779 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001780 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001781 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001782 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001783 virtual void destroy();
1784 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001785 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001786};
1787
Howard Hinnantc834c512011-11-29 18:15:50 +00001788template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001789void
Howard Hinnantc834c512011-11-29 18:15:50 +00001790__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001791 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001792{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001793 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001794}
1795
Howard Hinnantc834c512011-11-29 18:15:50 +00001796template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001797void
Howard Hinnantc834c512011-11-29 18:15:50 +00001798__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001799{
Howard Hinnantc834c512011-11-29 18:15:50 +00001800 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001801}
1802
Howard Hinnantc834c512011-11-29 18:15:50 +00001803template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001804void
Howard Hinnantc834c512011-11-29 18:15:50 +00001805__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001806{
Eric Fiselier0d109272014-10-23 06:24:45 +00001807 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1808 typedef allocator_traits<_Ap> _ATraits;
1809 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001810 _Ap __a(__f_.second());
1811 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001812 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001813}
1814
Howard Hinnantc834c512011-11-29 18:15:50 +00001815template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1816_Rp
1817__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001818{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001819 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001820}
1821
Howard Hinnant944510a2011-06-14 19:58:17 +00001822template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001823
Howard Hinnantc834c512011-11-29 18:15:50 +00001824template<class _Rp, class ..._ArgTypes>
1825class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001826{
Howard Hinnantc834c512011-11-29 18:15:50 +00001827 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001828 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001829 __base* __f_;
1830
1831public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001832 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001833
1834 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001835 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001836 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001837 template<class _Fp>
1838 __packaged_task_function(_Fp&& __f);
1839 template<class _Fp, class _Alloc>
1840 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001841
Howard Hinnant22448042012-07-21 17:46:55 +00001842 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1843 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001844
1845 __packaged_task_function(const __packaged_task_function&) = delete;
1846 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1847
1848 ~__packaged_task_function();
1849
Howard Hinnant22448042012-07-21 17:46:55 +00001850 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001851
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001852 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001853 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001854};
1855
Howard Hinnantc834c512011-11-29 18:15:50 +00001856template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001857__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001858{
1859 if (__f.__f_ == nullptr)
1860 __f_ = nullptr;
1861 else if (__f.__f_ == (__base*)&__f.__buf_)
1862 {
1863 __f_ = (__base*)&__buf_;
1864 __f.__f_->__move_to(__f_);
1865 }
1866 else
1867 {
1868 __f_ = __f.__f_;
1869 __f.__f_ = nullptr;
1870 }
1871}
1872
Howard Hinnantc834c512011-11-29 18:15:50 +00001873template<class _Rp, class ..._ArgTypes>
1874template <class _Fp>
1875__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001876 : __f_(nullptr)
1877{
Marshall Clow733d60e2014-04-07 13:32:26 +00001878 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001879 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001880 if (sizeof(_FF) <= sizeof(__buf_))
1881 {
1882 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001883 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001884 }
1885 else
1886 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001887 typedef allocator<_FF> _Ap;
1888 _Ap __a;
1889 typedef __allocator_destructor<_Ap> _Dp;
1890 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1891 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001892 __f_ = __hold.release();
1893 }
1894}
1895
Howard Hinnantc834c512011-11-29 18:15:50 +00001896template<class _Rp, class ..._ArgTypes>
1897template <class _Fp, class _Alloc>
1898__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1899 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001900 : __f_(nullptr)
1901{
Marshall Clow733d60e2014-04-07 13:32:26 +00001902 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001903 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001904 if (sizeof(_FF) <= sizeof(__buf_))
1905 {
1906 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001907 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001908 }
1909 else
1910 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001911 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001912 _Ap __a(__a0);
1913 typedef __allocator_destructor<_Ap> _Dp;
1914 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001915 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1916 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1917 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001918 }
1919}
1920
Howard Hinnantc834c512011-11-29 18:15:50 +00001921template<class _Rp, class ..._ArgTypes>
1922__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001923__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001924{
1925 if (__f_ == (__base*)&__buf_)
1926 __f_->destroy();
1927 else if (__f_)
1928 __f_->destroy_deallocate();
1929 __f_ = nullptr;
1930 if (__f.__f_ == nullptr)
1931 __f_ = nullptr;
1932 else if (__f.__f_ == (__base*)&__f.__buf_)
1933 {
1934 __f_ = (__base*)&__buf_;
1935 __f.__f_->__move_to(__f_);
1936 }
1937 else
1938 {
1939 __f_ = __f.__f_;
1940 __f.__f_ = nullptr;
1941 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001942 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001943}
1944
Howard Hinnantc834c512011-11-29 18:15:50 +00001945template<class _Rp, class ..._ArgTypes>
1946__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001947{
1948 if (__f_ == (__base*)&__buf_)
1949 __f_->destroy();
1950 else if (__f_)
1951 __f_->destroy_deallocate();
1952}
1953
Howard Hinnantc834c512011-11-29 18:15:50 +00001954template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001955void
Howard Hinnant22448042012-07-21 17:46:55 +00001956__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001957{
1958 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1959 {
1960 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1961 __base* __t = (__base*)&__tempbuf;
1962 __f_->__move_to(__t);
1963 __f_->destroy();
1964 __f_ = nullptr;
1965 __f.__f_->__move_to((__base*)&__buf_);
1966 __f.__f_->destroy();
1967 __f.__f_ = nullptr;
1968 __f_ = (__base*)&__buf_;
1969 __t->__move_to((__base*)&__f.__buf_);
1970 __t->destroy();
1971 __f.__f_ = (__base*)&__f.__buf_;
1972 }
1973 else if (__f_ == (__base*)&__buf_)
1974 {
1975 __f_->__move_to((__base*)&__f.__buf_);
1976 __f_->destroy();
1977 __f_ = __f.__f_;
1978 __f.__f_ = (__base*)&__f.__buf_;
1979 }
1980 else if (__f.__f_ == (__base*)&__f.__buf_)
1981 {
1982 __f.__f_->__move_to((__base*)&__buf_);
1983 __f.__f_->destroy();
1984 __f.__f_ = __f_;
1985 __f_ = (__base*)&__buf_;
1986 }
1987 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001988 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001989}
1990
Howard Hinnantc834c512011-11-29 18:15:50 +00001991template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001992inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001993_Rp
1994__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001995{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001996 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001997}
1998
Howard Hinnantc834c512011-11-29 18:15:50 +00001999template<class _Rp, class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002000class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002001{
2002public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002003 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004
2005private:
2006 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2007 promise<result_type> __p_;
2008
2009public:
2010 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002012 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002013 template <class _Fp,
2014 class = typename enable_if
2015 <
2016 !is_same<
2017 typename decay<_Fp>::type,
2018 packaged_task
2019 >::value
2020 >::type
2021 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002022 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002023 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002024 template <class _Fp, class _Allocator,
2025 class = typename enable_if
2026 <
2027 !is_same<
2028 typename decay<_Fp>::type,
2029 packaged_task
2030 >::value
2031 >::type
2032 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002033 _LIBCPP_INLINE_VISIBILITY
Marshall Clowc317e022015-06-30 14:16:49 +00002034 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002035 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002036 __p_(allocator_arg, __a) {}
2037 // ~packaged_task() = default;
2038
2039 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002040 packaged_task(const packaged_task&) = delete;
2041 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002042
2043 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002045 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002046 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002048 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002049 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002050 __f_ = _VSTD::move(__other.__f_);
2051 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002052 return *this;
2053 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002055 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002056 {
2057 __f_.swap(__other.__f_);
2058 __p_.swap(__other.__p_);
2059 }
2060
Howard Hinnant684902d2010-09-22 14:16:26 +00002061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002062 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002063
2064 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002066 future<result_type> get_future() {return __p_.get_future();}
2067
2068 // execution
2069 void operator()(_ArgTypes... __args);
2070 void make_ready_at_thread_exit(_ArgTypes... __args);
2071
2072 void reset();
2073};
2074
Howard Hinnantc834c512011-11-29 18:15:50 +00002075template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002076void
Howard Hinnantc834c512011-11-29 18:15:50 +00002077packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002078{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002079 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002080 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002082 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002083#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002084 try
2085 {
2086#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002087 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002088#ifndef _LIBCPP_NO_EXCEPTIONS
2089 }
2090 catch (...)
2091 {
2092 __p_.set_exception(current_exception());
2093 }
2094#endif // _LIBCPP_NO_EXCEPTIONS
2095}
2096
Howard Hinnantc834c512011-11-29 18:15:50 +00002097template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002098void
Howard Hinnantc834c512011-11-29 18:15:50 +00002099packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002100{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002101 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002102 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002103 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002104 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002105#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002106 try
2107 {
2108#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002109 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002110#ifndef _LIBCPP_NO_EXCEPTIONS
2111 }
2112 catch (...)
2113 {
2114 __p_.set_exception_at_thread_exit(current_exception());
2115 }
2116#endif // _LIBCPP_NO_EXCEPTIONS
2117}
2118
Howard Hinnantc834c512011-11-29 18:15:50 +00002119template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002120void
Howard Hinnantc834c512011-11-29 18:15:50 +00002121packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002122{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002123 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002124 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002125 __p_ = promise<result_type>();
2126}
2127
2128template<class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002129class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002130{
2131public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002132 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002133
2134private:
2135 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2136 promise<result_type> __p_;
2137
2138public:
2139 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002140 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002141 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002142 template <class _Fp,
2143 class = typename enable_if
2144 <
2145 !is_same<
2146 typename decay<_Fp>::type,
2147 packaged_task
2148 >::value
2149 >::type
2150 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002151 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002152 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002153 template <class _Fp, class _Allocator,
2154 class = typename enable_if
2155 <
2156 !is_same<
2157 typename decay<_Fp>::type,
2158 packaged_task
2159 >::value
2160 >::type
2161 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002162 _LIBCPP_INLINE_VISIBILITY
Marshall Clow976e4822015-06-30 18:28:35 +00002163 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002164 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002165 __p_(allocator_arg, __a) {}
2166 // ~packaged_task() = default;
2167
2168 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002169 packaged_task(const packaged_task&) = delete;
2170 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002171
2172 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002173 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002174 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002175 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002177 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002178 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002179 __f_ = _VSTD::move(__other.__f_);
2180 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002181 return *this;
2182 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002183 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002184 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002185 {
2186 __f_.swap(__other.__f_);
2187 __p_.swap(__other.__p_);
2188 }
2189
Howard Hinnant684902d2010-09-22 14:16:26 +00002190 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002191 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002192
2193 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002194 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002195 future<result_type> get_future() {return __p_.get_future();}
2196
2197 // execution
2198 void operator()(_ArgTypes... __args);
2199 void make_ready_at_thread_exit(_ArgTypes... __args);
2200
2201 void reset();
2202};
2203
2204template<class ..._ArgTypes>
2205void
2206packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2207{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002208 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002209 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002210 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002211 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002212#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002213 try
2214 {
2215#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002216 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002217 __p_.set_value();
2218#ifndef _LIBCPP_NO_EXCEPTIONS
2219 }
2220 catch (...)
2221 {
2222 __p_.set_exception(current_exception());
2223 }
2224#endif // _LIBCPP_NO_EXCEPTIONS
2225}
2226
2227template<class ..._ArgTypes>
2228void
2229packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2230{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002231 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002232 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002233 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002234 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002235#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002236 try
2237 {
2238#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002239 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002240 __p_.set_value_at_thread_exit();
2241#ifndef _LIBCPP_NO_EXCEPTIONS
2242 }
2243 catch (...)
2244 {
2245 __p_.set_exception_at_thread_exit(current_exception());
2246 }
2247#endif // _LIBCPP_NO_EXCEPTIONS
2248}
2249
2250template<class ..._ArgTypes>
2251void
2252packaged_task<void(_ArgTypes...)>::reset()
2253{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002254 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002255 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002256 __p_ = promise<result_type>();
2257}
2258
2259template <class _Callable>
2260inline _LIBCPP_INLINE_VISIBILITY
2261void
Howard Hinnant22448042012-07-21 17:46:55 +00002262swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002263{
2264 __x.swap(__y);
2265}
2266
2267template <class _Callable, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002268struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00002269 : public true_type {};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002270
Howard Hinnantc834c512011-11-29 18:15:50 +00002271template <class _Rp, class _Fp>
2272future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002273#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002274__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002275#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002276__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002277#endif
2278{
Howard Hinnantc834c512011-11-29 18:15:50 +00002279 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2280 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2281 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002282}
2283
Howard Hinnantc834c512011-11-29 18:15:50 +00002284template <class _Rp, class _Fp>
2285future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002286#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002287__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002288#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002289__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002290#endif
2291{
Howard Hinnantc834c512011-11-29 18:15:50 +00002292 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2293 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2294 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2295 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002296}
2297
Howard Hinnantc834c512011-11-29 18:15:50 +00002298template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002299class __async_func
2300{
Howard Hinnantc834c512011-11-29 18:15:50 +00002301 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002302
2303public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002304 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002305
2306 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002307 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002308 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002309
2310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002311 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002312
Howard Hinnantc834c512011-11-29 18:15:50 +00002313 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002314 {
2315 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2316 return __execute(_Index());
2317 }
2318private:
2319 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002320 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002321 __execute(__tuple_indices<_Indices...>)
2322 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002323 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002324 }
2325};
2326
Marshall Clowd56a5b62013-11-03 22:06:53 +00002327inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002328{ return (int(__policy) & int(__value)) != 0; }
2329
Howard Hinnantc834c512011-11-29 18:15:50 +00002330template <class _Fp, class... _Args>
2331future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2332async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002333{
Howard Hinnantc834c512011-11-29 18:15:50 +00002334 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2335 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002336
2337#ifndef _LIBCPP_NO_EXCEPTIONS
2338 try
2339 {
2340#endif
2341 if (__does_policy_contain(__policy, launch::async))
2342 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002343 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002344#ifndef _LIBCPP_NO_EXCEPTIONS
2345 }
2346 catch ( ... ) { if (__policy == launch::async) throw ; }
2347#endif
2348
2349 if (__does_policy_contain(__policy, launch::deferred))
2350 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002351 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002352 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002353}
2354
Howard Hinnantc834c512011-11-29 18:15:50 +00002355template <class _Fp, class... _Args>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002356inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002357future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2358async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002359{
Howard Hinnantc834c512011-11-29 18:15:50 +00002360 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002361 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002362}
2363
2364#endif // _LIBCPP_HAS_NO_VARIADICS
2365
Howard Hinnante6a10852010-09-03 21:46:37 +00002366// shared_future
2367
Howard Hinnantc834c512011-11-29 18:15:50 +00002368template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002369class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002370{
Howard Hinnantc834c512011-11-29 18:15:50 +00002371 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002372
2373public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002375 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002376 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002377 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2378 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002379#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002381 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002382 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002384 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002385 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002386#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002387 ~shared_future();
2388 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002389#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002391 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002392 {
2393 shared_future(std::move(__rhs)).swap(*this);
2394 return *this;
2395 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002396#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002397
2398 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002400 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002401
Howard Hinnant684902d2010-09-22 14:16:26 +00002402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002403 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002404
2405 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002406 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002407 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002408
Howard Hinnant684902d2010-09-22 14:16:26 +00002409 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002410 void wait() const {__state_->wait();}
2411 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002412 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002413 future_status
2414 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2415 {return __state_->wait_for(__rel_time);}
2416 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002418 future_status
2419 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2420 {return __state_->wait_until(__abs_time);}
2421};
2422
Howard Hinnantc834c512011-11-29 18:15:50 +00002423template <class _Rp>
2424shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002425{
2426 if (__state_)
2427 __state_->__release_shared();
2428}
2429
Howard Hinnantc834c512011-11-29 18:15:50 +00002430template <class _Rp>
2431shared_future<_Rp>&
2432shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002433{
2434 if (__rhs.__state_)
2435 __rhs.__state_->__add_shared();
2436 if (__state_)
2437 __state_->__release_shared();
2438 __state_ = __rhs.__state_;
2439 return *this;
2440}
2441
Howard Hinnantc834c512011-11-29 18:15:50 +00002442template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002443class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002444{
Howard Hinnantc834c512011-11-29 18:15:50 +00002445 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002446
2447public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002449 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002451 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2452 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002453#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002454 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002455 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002456 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002458 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002459 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002460#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002461 ~shared_future();
2462 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002463#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002464 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002465 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002466 {
2467 shared_future(std::move(__rhs)).swap(*this);
2468 return *this;
2469 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002470#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002471
2472 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002474 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002475
Howard Hinnant684902d2010-09-22 14:16:26 +00002476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002477 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002478
2479 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002480 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002481 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002482
Howard Hinnant684902d2010-09-22 14:16:26 +00002483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002484 void wait() const {__state_->wait();}
2485 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002486 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002487 future_status
2488 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2489 {return __state_->wait_for(__rel_time);}
2490 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002491 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002492 future_status
2493 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2494 {return __state_->wait_until(__abs_time);}
2495};
2496
Howard Hinnantc834c512011-11-29 18:15:50 +00002497template <class _Rp>
2498shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002499{
2500 if (__state_)
2501 __state_->__release_shared();
2502}
2503
Howard Hinnantc834c512011-11-29 18:15:50 +00002504template <class _Rp>
2505shared_future<_Rp&>&
2506shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002507{
2508 if (__rhs.__state_)
2509 __rhs.__state_->__add_shared();
2510 if (__state_)
2511 __state_->__release_shared();
2512 __state_ = __rhs.__state_;
2513 return *this;
2514}
2515
2516template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00002517class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002518{
2519 __assoc_sub_state* __state_;
2520
2521public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002522 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002523 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002525 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2526 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002527#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002529 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002530 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002531 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002532 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002533 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002534#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002535 ~shared_future();
2536 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002537#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002539 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002540 {
2541 shared_future(std::move(__rhs)).swap(*this);
2542 return *this;
2543 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002544#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002545
2546 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002548 void get() const {__state_->copy();}
2549
Howard Hinnant684902d2010-09-22 14:16:26 +00002550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002551 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002552
2553 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002555 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002556
Howard Hinnant684902d2010-09-22 14:16:26 +00002557 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002558 void wait() const {__state_->wait();}
2559 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002561 future_status
2562 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2563 {return __state_->wait_for(__rel_time);}
2564 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002566 future_status
2567 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2568 {return __state_->wait_until(__abs_time);}
2569};
2570
Howard Hinnantc834c512011-11-29 18:15:50 +00002571template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002572inline _LIBCPP_INLINE_VISIBILITY
2573void
Howard Hinnant22448042012-07-21 17:46:55 +00002574swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002575{
2576 __x.swap(__y);
2577}
2578
Howard Hinnantc834c512011-11-29 18:15:50 +00002579template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002580inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002581shared_future<_Rp>
2582future<_Rp>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002583{
Howard Hinnantc834c512011-11-29 18:15:50 +00002584 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002585}
2586
Howard Hinnantc834c512011-11-29 18:15:50 +00002587template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002588inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002589shared_future<_Rp&>
2590future<_Rp&>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002591{
Howard Hinnantc834c512011-11-29 18:15:50 +00002592 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002593}
2594
Howard Hinnante65e8e32010-12-02 16:45:21 +00002595#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2596
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002597inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002598shared_future<void>
2599future<void>::share()
2600{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002601 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002602}
2603
Howard Hinnante65e8e32010-12-02 16:45:21 +00002604#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2605
Howard Hinnantc51e1022010-05-11 19:42:16 +00002606_LIBCPP_END_NAMESPACE_STD
2607
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002608#endif // !_LIBCPP_HAS_NO_THREADS
2609
Howard Hinnantc51e1022010-05-11 19:42:16 +00002610#endif // _LIBCPP_FUTURE