blob: 367eab905124369e67ef4661e2bddaa984e1278f [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
Howard Hinnantcd942f12013-09-14 18:20:10 +000022 future_already_retrieved = 1,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000023 promise_already_satisfied,
Howard Hinnantcd942f12013-09-14 18:20:10 +000024 no_state,
25 broken_promise
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000026};
27
28enum class launch
29{
Howard Hinnant66895642010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000033};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000045
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000056};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000073
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000311template <class F, class... Args>
Howard Hinnant0836f872013-09-21 18:17:23 +0000312 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
Howard Hinnant0836f872013-09-21 18:17:23 +0000316 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantf5256e12010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
325 typedef R result_type;
326
327 // construction and destruction
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
Marshall Clow07546f32015-06-30 14:16:49 +0000332 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000333 ~packaged_task();
334
335 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000340 packaged_task(packaged_task&& other) noexcept;
341 packaged_task& operator=(packaged_task&& other) noexcept;
342 void swap(packaged_task& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000343
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000358
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant47499b12010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372
Howard Hinnant08e17472011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000375#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376
Jonathan Roelofsbaed05d2014-09-05 20:28:44 +0000377#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +0000378#error <future> is not supported on this single threaded system
379#else // !_LIBCPP_HAS_NO_THREADS
380
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381_LIBCPP_BEGIN_NAMESPACE_STD
382
383//enum class future_errc
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000384_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000385{
Howard Hinnantcd942f12013-09-14 18:20:10 +0000386 future_already_retrieved = 1,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000387 promise_already_satisfied,
Howard Hinnantcd942f12013-09-14 18:20:10 +0000388 no_state,
389 broken_promise
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000390};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000391_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000392
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000393template <>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000394struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000395
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000396#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397template <>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000398struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000399#endif
400
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401//enum class launch
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000402_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403{
Howard Hinnant66895642010-11-23 18:33:54 +0000404 async = 1,
405 deferred = 2,
406 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000407};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409
Howard Hinnantf491e512013-06-29 18:38:17 +0000410#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411
412#ifdef _LIBCXX_UNDERLYING_TYPE
413typedef underlying_type<launch>::type __launch_underlying_type;
414#else
415typedef int __launch_underlying_type;
416#endif
417
418inline _LIBCPP_INLINE_VISIBILITY
419_LIBCPP_CONSTEXPR
420launch
421operator&(launch __x, launch __y)
422{
423 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
424 static_cast<__launch_underlying_type>(__y));
425}
426
427inline _LIBCPP_INLINE_VISIBILITY
428_LIBCPP_CONSTEXPR
429launch
430operator|(launch __x, launch __y)
431{
432 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
433 static_cast<__launch_underlying_type>(__y));
434}
435
436inline _LIBCPP_INLINE_VISIBILITY
437_LIBCPP_CONSTEXPR
438launch
439operator^(launch __x, launch __y)
440{
441 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
442 static_cast<__launch_underlying_type>(__y));
443}
444
445inline _LIBCPP_INLINE_VISIBILITY
446_LIBCPP_CONSTEXPR
447launch
448operator~(launch __x)
449{
Howard Hinnant6a683bf2013-07-02 18:01:41 +0000450 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantf491e512013-06-29 18:38:17 +0000451}
452
453inline _LIBCPP_INLINE_VISIBILITY
454launch&
455operator&=(launch& __x, launch __y)
456{
457 __x = __x & __y; return __x;
458}
459
460inline _LIBCPP_INLINE_VISIBILITY
461launch&
462operator|=(launch& __x, launch __y)
463{
464 __x = __x | __y; return __x;
465}
466
467inline _LIBCPP_INLINE_VISIBILITY
468launch&
469operator^=(launch& __x, launch __y)
470{
471 __x = __x ^ __y; return __x;
472}
473
474#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
475
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000476//enum class future_status
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000477_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000478{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000479 ready,
480 timeout,
481 deferred
482};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000483_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000484
Howard Hinnant83eade62013-03-06 23:30:19 +0000485_LIBCPP_FUNC_VIS
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000486const error_category& future_category() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000487
488inline _LIBCPP_INLINE_VISIBILITY
489error_code
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000490make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000491{
492 return error_code(static_cast<int>(__e), future_category());
493}
494
495inline _LIBCPP_INLINE_VISIBILITY
496error_condition
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000497make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000498{
499 return error_condition(static_cast<int>(__e), future_category());
500}
501
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000502class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000503 : public logic_error
504{
505 error_code __ec_;
506public:
507 future_error(error_code __ec);
508
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000509 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000510 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52 +0000511
512 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000513};
514
Eric Fiselier423ca202015-10-02 21:25:15 +0000515inline _LIBCPP_ALWAYS_INLINE
516void __throw_future_error(future_errc _Ev)
Marshall Clowa1899742015-09-03 15:11:32 +0000517{
518#ifndef _LIBCPP_NO_EXCEPTIONS
519 throw future_error(make_error_code(_Ev));
520#else
521 assert(!"future_error");
522#endif
523}
524
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000525class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant47499b12010-08-27 20:10:19 +0000526 : public __shared_count
527{
528protected:
529 exception_ptr __exception_;
530 mutable mutex __mut_;
531 mutable condition_variable __cv_;
532 unsigned __state_;
533
Howard Hinnant1694d232011-05-28 14:41:13 +0000534 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000535 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000536public:
537 enum
538 {
539 __constructed = 1,
540 __future_attached = 2,
541 ready = 4,
542 deferred = 8
543 };
544
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000545 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000546 __assoc_sub_state() : __state_(0) {}
547
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000549 bool __has_value() const
550 {return (__state_ & __constructed) || (__exception_ != nullptr);}
551
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1b031c92013-01-14 20:01:24 +0000553 void __set_future_attached()
554 {
555 lock_guard<mutex> __lk(__mut_);
556 __state_ |= __future_attached;
557 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000558 _LIBCPP_INLINE_VISIBILITY
Marshall Clow9de3d4c2013-10-13 01:02:45 +0000559 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant47499b12010-08-27 20:10:19 +0000560
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000562 void __set_deferred() {__state_ |= deferred;}
563
Howard Hinnant47499b12010-08-27 20:10:19 +0000564 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000565 _LIBCPP_INLINE_VISIBILITY
Marshall Clow9de3d4c2013-10-13 01:02:45 +0000566 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant47499b12010-08-27 20:10:19 +0000567
568 void set_value();
569 void set_value_at_thread_exit();
570
571 void set_exception(exception_ptr __p);
572 void set_exception_at_thread_exit(exception_ptr __p);
573
574 void copy();
575
Howard Hinnant54da3382010-08-30 18:46:21 +0000576 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000577 template <class _Rep, class _Period>
578 future_status
579 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
580 template <class _Clock, class _Duration>
581 future_status
582 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000583
584 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000585};
586
Howard Hinnantf39daa82010-08-28 21:01:06 +0000587template <class _Clock, class _Duration>
588future_status
589__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
590{
591 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000592 if (__state_ & deferred)
593 return future_status::deferred;
594 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000595 __cv_.wait_until(__lk, __abs_time);
596 if (__state_ & ready)
597 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000598 return future_status::timeout;
599}
600
601template <class _Rep, class _Period>
602inline _LIBCPP_INLINE_VISIBILITY
603future_status
604__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
605{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000606 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000607}
608
Howard Hinnant99968442011-11-29 18:15:50 +0000609template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000610class __assoc_state
611 : public __assoc_sub_state
612{
613 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000614 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000615protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000616 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000617
Howard Hinnant1694d232011-05-28 14:41:13 +0000618 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000619public:
620
621 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000622#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000623 void set_value(_Arg&& __arg);
624#else
625 void set_value(_Arg& __arg);
626#endif
627
628 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000629#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000630 void set_value_at_thread_exit(_Arg&& __arg);
631#else
632 void set_value_at_thread_exit(_Arg& __arg);
633#endif
634
Howard Hinnant99968442011-11-29 18:15:50 +0000635 _Rp move();
636 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000637};
638
Howard Hinnant99968442011-11-29 18:15:50 +0000639template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000640void
Howard Hinnant99968442011-11-29 18:15:50 +0000641__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000642{
643 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000644 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000645 delete this;
646}
647
Howard Hinnant99968442011-11-29 18:15:50 +0000648template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000649template <class _Arg>
650void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000651#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000652__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000653#else
Howard Hinnant99968442011-11-29 18:15:50 +0000654__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000655#endif
656{
657 unique_lock<mutex> __lk(this->__mut_);
658 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000659 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant99968442011-11-29 18:15:50 +0000660 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000661 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant47499b12010-08-27 20:10:19 +0000662 __cv_.notify_all();
663}
664
Howard Hinnant99968442011-11-29 18:15:50 +0000665template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000666template <class _Arg>
667void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000668#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000669__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000670#else
Howard Hinnant99968442011-11-29 18:15:50 +0000671__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000672#endif
673{
674 unique_lock<mutex> __lk(this->__mut_);
675 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000676 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant99968442011-11-29 18:15:50 +0000677 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000678 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000679 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000680}
681
Howard Hinnant99968442011-11-29 18:15:50 +0000682template <class _Rp>
683_Rp
684__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000685{
686 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000687 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000688 if (this->__exception_ != nullptr)
689 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000690 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000691}
692
Howard Hinnant99968442011-11-29 18:15:50 +0000693template <class _Rp>
694typename add_lvalue_reference<_Rp>::type
695__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000696{
697 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000698 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000699 if (this->__exception_ != nullptr)
700 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000701 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000702}
703
Howard Hinnant99968442011-11-29 18:15:50 +0000704template <class _Rp>
705class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000706 : public __assoc_sub_state
707{
708 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000709 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000710protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000711 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000712
Howard Hinnant1694d232011-05-28 14:41:13 +0000713 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000714public:
715
Howard Hinnant99968442011-11-29 18:15:50 +0000716 void set_value(_Rp& __arg);
717 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000718
Howard Hinnant99968442011-11-29 18:15:50 +0000719 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000720};
721
Howard Hinnant99968442011-11-29 18:15:50 +0000722template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000723void
Howard Hinnant99968442011-11-29 18:15:50 +0000724__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000725{
726 delete this;
727}
728
Howard Hinnant99968442011-11-29 18:15:50 +0000729template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000730void
Howard Hinnant99968442011-11-29 18:15:50 +0000731__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000732{
733 unique_lock<mutex> __lk(this->__mut_);
734 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000735 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000736 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000737 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000738 __cv_.notify_all();
739}
740
Howard Hinnant99968442011-11-29 18:15:50 +0000741template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000742void
Howard Hinnant99968442011-11-29 18:15:50 +0000743__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000744{
745 unique_lock<mutex> __lk(this->__mut_);
746 if (this->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +0000747 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000748 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000749 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000750 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000751}
752
Howard Hinnant99968442011-11-29 18:15:50 +0000753template <class _Rp>
754_Rp&
755__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000756{
757 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000758 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000759 if (this->__exception_ != nullptr)
760 rethrow_exception(this->__exception_);
761 return *__value_;
762}
763
Howard Hinnant99968442011-11-29 18:15:50 +0000764template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000765class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000766 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000767{
Howard Hinnant99968442011-11-29 18:15:50 +0000768 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000769 _Alloc __alloc_;
770
Howard Hinnant1694d232011-05-28 14:41:13 +0000771 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000772public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000773 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000774 explicit __assoc_state_alloc(const _Alloc& __a)
775 : __alloc_(__a) {}
776};
777
Howard Hinnant99968442011-11-29 18:15:50 +0000778template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000779void
Howard Hinnant99968442011-11-29 18:15:50 +0000780__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000781{
782 if (this->__state_ & base::__constructed)
Howard Hinnanta4e87ab2013-08-08 18:38:55 +0000783 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselier8492cd82015-02-05 23:01:40 +0000784 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
785 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000786 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000787 _Al __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000788 this->~__assoc_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000789 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant47499b12010-08-27 20:10:19 +0000790}
791
Howard Hinnant99968442011-11-29 18:15:50 +0000792template <class _Rp, class _Alloc>
793class __assoc_state_alloc<_Rp&, _Alloc>
794 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000795{
Howard Hinnant99968442011-11-29 18:15:50 +0000796 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000797 _Alloc __alloc_;
798
Howard Hinnant1694d232011-05-28 14:41:13 +0000799 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000800public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000801 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000802 explicit __assoc_state_alloc(const _Alloc& __a)
803 : __alloc_(__a) {}
804};
805
Howard Hinnant99968442011-11-29 18:15:50 +0000806template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000807void
Howard Hinnant99968442011-11-29 18:15:50 +0000808__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000809{
Eric Fiselier8492cd82015-02-05 23:01:40 +0000810 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
811 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000812 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000813 _Al __a(__alloc_);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000814 this->~__assoc_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000815 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000816}
817
Howard Hinnant47499b12010-08-27 20:10:19 +0000818template <class _Alloc>
819class __assoc_sub_state_alloc
820 : public __assoc_sub_state
821{
822 typedef __assoc_sub_state base;
823 _Alloc __alloc_;
824
Howard Hinnant1694d232011-05-28 14:41:13 +0000825 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000826public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000827 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000828 explicit __assoc_sub_state_alloc(const _Alloc& __a)
829 : __alloc_(__a) {}
830};
831
832template <class _Alloc>
833void
Howard Hinnant1694d232011-05-28 14:41:13 +0000834__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000835{
Eric Fiselier8492cd82015-02-05 23:01:40 +0000836 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
837 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000838 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselier8492cd82015-02-05 23:01:40 +0000839 _Al __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000840 this->~__assoc_sub_state_alloc();
Eric Fiselier4d2413c2014-10-23 06:24:45 +0000841 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant47499b12010-08-27 20:10:19 +0000842}
843
Howard Hinnant99968442011-11-29 18:15:50 +0000844template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000845class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000846 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000847{
Howard Hinnant99968442011-11-29 18:15:50 +0000848 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000849
Howard Hinnant99968442011-11-29 18:15:50 +0000850 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000851
852public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000853#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000854 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000855#endif
856
857 virtual void __execute();
858};
859
Howard Hinnant73d21a42010-09-04 23:28:19 +0000860#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000861
Howard Hinnant99968442011-11-29 18:15:50 +0000862template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000863inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000864__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
865 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000866{
867 this->__set_deferred();
868}
869
Howard Hinnant73d21a42010-09-04 23:28:19 +0000870#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000871
Howard Hinnant99968442011-11-29 18:15:50 +0000872template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000873void
Howard Hinnant99968442011-11-29 18:15:50 +0000874__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000875{
876#ifndef _LIBCPP_NO_EXCEPTIONS
877 try
878 {
879#endif // _LIBCPP_NO_EXCEPTIONS
880 this->set_value(__func_());
881#ifndef _LIBCPP_NO_EXCEPTIONS
882 }
883 catch (...)
884 {
885 this->set_exception(current_exception());
886 }
887#endif // _LIBCPP_NO_EXCEPTIONS
888}
889
Howard Hinnant99968442011-11-29 18:15:50 +0000890template <class _Fp>
891class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000892 : public __assoc_sub_state
893{
894 typedef __assoc_sub_state base;
895
Howard Hinnant99968442011-11-29 18:15:50 +0000896 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000897
898public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000899#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000900 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000901#endif
902
903 virtual void __execute();
904};
905
Howard Hinnant73d21a42010-09-04 23:28:19 +0000906#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000907
Howard Hinnant99968442011-11-29 18:15:50 +0000908template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000909inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000910__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
911 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000912{
913 this->__set_deferred();
914}
915
Howard Hinnant73d21a42010-09-04 23:28:19 +0000916#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000917
Howard Hinnant99968442011-11-29 18:15:50 +0000918template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000919void
Howard Hinnant99968442011-11-29 18:15:50 +0000920__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000921{
922#ifndef _LIBCPP_NO_EXCEPTIONS
923 try
924 {
925#endif // _LIBCPP_NO_EXCEPTIONS
926 __func_();
927 this->set_value();
928#ifndef _LIBCPP_NO_EXCEPTIONS
929 }
930 catch (...)
931 {
932 this->set_exception(current_exception());
933 }
934#endif // _LIBCPP_NO_EXCEPTIONS
935}
936
Howard Hinnant99968442011-11-29 18:15:50 +0000937template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000938class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000939 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000940{
Howard Hinnant99968442011-11-29 18:15:50 +0000941 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000942
Howard Hinnant99968442011-11-29 18:15:50 +0000943 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000944
Howard Hinnant1694d232011-05-28 14:41:13 +0000945 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000946public:
947#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000948 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000949#endif
950
951 virtual void __execute();
952};
953
954#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
955
Howard Hinnant99968442011-11-29 18:15:50 +0000956template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000957inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000958__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
959 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000960{
961}
962
963#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
964
Howard Hinnant99968442011-11-29 18:15:50 +0000965template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000966void
Howard Hinnant99968442011-11-29 18:15:50 +0000967__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000968{
969#ifndef _LIBCPP_NO_EXCEPTIONS
970 try
971 {
972#endif // _LIBCPP_NO_EXCEPTIONS
973 this->set_value(__func_());
974#ifndef _LIBCPP_NO_EXCEPTIONS
975 }
976 catch (...)
977 {
978 this->set_exception(current_exception());
979 }
980#endif // _LIBCPP_NO_EXCEPTIONS
981}
982
Howard Hinnant99968442011-11-29 18:15:50 +0000983template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000984void
Howard Hinnant99968442011-11-29 18:15:50 +0000985__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000986{
987 this->wait();
988 base::__on_zero_shared();
989}
990
Howard Hinnant99968442011-11-29 18:15:50 +0000991template <class _Fp>
992class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000993 : public __assoc_sub_state
994{
995 typedef __assoc_sub_state base;
996
Howard Hinnant99968442011-11-29 18:15:50 +0000997 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000998
Howard Hinnant1694d232011-05-28 14:41:13 +0000999 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +00001000public:
1001#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001002 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001003#endif
1004
1005 virtual void __execute();
1006};
1007
1008#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1009
Howard Hinnant99968442011-11-29 18:15:50 +00001010template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001011inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001012__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1013 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +00001014{
1015}
1016
1017#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018
Howard Hinnant99968442011-11-29 18:15:50 +00001019template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001020void
Howard Hinnant99968442011-11-29 18:15:50 +00001021__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +00001022{
1023#ifndef _LIBCPP_NO_EXCEPTIONS
1024 try
1025 {
1026#endif // _LIBCPP_NO_EXCEPTIONS
1027 __func_();
1028 this->set_value();
1029#ifndef _LIBCPP_NO_EXCEPTIONS
1030 }
1031 catch (...)
1032 {
1033 this->set_exception(current_exception());
1034 }
1035#endif // _LIBCPP_NO_EXCEPTIONS
1036}
1037
Howard Hinnant99968442011-11-29 18:15:50 +00001038template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001039void
Howard Hinnant99968442011-11-29 18:15:50 +00001040__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +00001041{
1042 this->wait();
1043 base::__on_zero_shared();
1044}
1045
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001046template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1047template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +00001048
1049// future
1050
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001051template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001052
Howard Hinnant99968442011-11-29 18:15:50 +00001053template <class _Rp, class _Fp>
1054future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001055#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001056__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001057#else
Howard Hinnant99968442011-11-29 18:15:50 +00001058__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001059#endif
1060
Howard Hinnant99968442011-11-29 18:15:50 +00001061template <class _Rp, class _Fp>
1062future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001063#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001064__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001065#else
Howard Hinnant99968442011-11-29 18:15:50 +00001066__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001067#endif
1068
Howard Hinnant99968442011-11-29 18:15:50 +00001069template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001070class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant47499b12010-08-27 20:10:19 +00001071{
Howard Hinnant99968442011-11-29 18:15:50 +00001072 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001073
Howard Hinnant99968442011-11-29 18:15:50 +00001074 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001075
1076 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001077 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001078
Howard Hinnant73d21a42010-09-04 23:28:19 +00001079#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001080 template <class _R1, class _Fp>
1081 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1082 template <class _R1, class _Fp>
1083 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001084#else
Howard Hinnant99968442011-11-29 18:15:50 +00001085 template <class _R1, class _Fp>
1086 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1087 template <class _R1, class _Fp>
1088 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001089#endif
1090
Howard Hinnant47499b12010-08-27 20:10:19 +00001091public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001092 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001093 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001094#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001095 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001096 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001097 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1098 future(const future&) = delete;
1099 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001100 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001101 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001102 {
1103 future(std::move(__rhs)).swap(*this);
1104 return *this;
1105 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001106#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001107private:
1108 future(const future&);
1109 future& operator=(const future&);
1110public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001111#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001112 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001113 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001114
1115 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001116 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001117
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001118 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001119 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001120
1121 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001122 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001123 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001124
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001125 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001126 void wait() const {__state_->wait();}
1127 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001128 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001129 future_status
1130 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1131 {return __state_->wait_for(__rel_time);}
1132 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001133 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001134 future_status
1135 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1136 {return __state_->wait_until(__abs_time);}
1137};
1138
Howard Hinnant99968442011-11-29 18:15:50 +00001139template <class _Rp>
1140future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001141 : __state_(__state)
1142{
1143 if (__state_->__has_future_attached())
Eric Fiselier423ca202015-10-02 21:25:15 +00001144 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant47499b12010-08-27 20:10:19 +00001145 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001146 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001147}
1148
Howard Hinnant54da3382010-08-30 18:46:21 +00001149struct __release_shared_count
1150{
1151 void operator()(__shared_count* p) {p->__release_shared();}
1152};
1153
Howard Hinnant99968442011-11-29 18:15:50 +00001154template <class _Rp>
1155future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001156{
1157 if (__state_)
1158 __state_->__release_shared();
1159}
1160
Howard Hinnant99968442011-11-29 18:15:50 +00001161template <class _Rp>
1162_Rp
1163future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001164{
Howard Hinnant54da3382010-08-30 18:46:21 +00001165 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001166 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001167 __state_ = nullptr;
1168 return __s->move();
1169}
1170
Howard Hinnant99968442011-11-29 18:15:50 +00001171template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001172class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001173{
Howard Hinnant99968442011-11-29 18:15:50 +00001174 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001175
Howard Hinnant99968442011-11-29 18:15:50 +00001176 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001177
1178 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001179 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001180
Howard Hinnant73d21a42010-09-04 23:28:19 +00001181#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001182 template <class _R1, class _Fp>
1183 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1184 template <class _R1, class _Fp>
1185 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001186#else
Howard Hinnant99968442011-11-29 18:15:50 +00001187 template <class _R1, class _Fp>
1188 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1189 template <class _R1, class _Fp>
1190 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001191#endif
1192
Howard Hinnant47499b12010-08-27 20:10:19 +00001193public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001194 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001195 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001196#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001198 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001199 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1200 future(const future&) = delete;
1201 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001202 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001203 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001204 {
1205 future(std::move(__rhs)).swap(*this);
1206 return *this;
1207 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001208#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001209private:
1210 future(const future&);
1211 future& operator=(const future&);
1212public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001213#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001214 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001215 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001216
1217 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001218 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001219
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001220 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001221 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001222
1223 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001224 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001225 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001226
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001227 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001228 void wait() const {__state_->wait();}
1229 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001230 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001231 future_status
1232 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1233 {return __state_->wait_for(__rel_time);}
1234 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001235 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001236 future_status
1237 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1238 {return __state_->wait_until(__abs_time);}
1239};
1240
Howard Hinnant99968442011-11-29 18:15:50 +00001241template <class _Rp>
1242future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001243 : __state_(__state)
1244{
1245 if (__state_->__has_future_attached())
Eric Fiselier423ca202015-10-02 21:25:15 +00001246 __throw_future_error(future_errc::future_already_retrieved);
Howard Hinnant47499b12010-08-27 20:10:19 +00001247 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001248 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001249}
1250
Howard Hinnant99968442011-11-29 18:15:50 +00001251template <class _Rp>
1252future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001253{
1254 if (__state_)
1255 __state_->__release_shared();
1256}
1257
Howard Hinnant99968442011-11-29 18:15:50 +00001258template <class _Rp>
1259_Rp&
1260future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001261{
Howard Hinnant54da3382010-08-30 18:46:21 +00001262 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001263 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001264 __state_ = nullptr;
1265 return __s->copy();
1266}
1267
1268template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001269class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001270{
1271 __assoc_sub_state* __state_;
1272
1273 explicit future(__assoc_sub_state* __state);
1274
1275 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001276 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001277
Howard Hinnant73d21a42010-09-04 23:28:19 +00001278#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001279 template <class _R1, class _Fp>
1280 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1281 template <class _R1, class _Fp>
1282 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001283#else
Howard Hinnant99968442011-11-29 18:15:50 +00001284 template <class _R1, class _Fp>
1285 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1286 template <class _R1, class _Fp>
1287 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001288#endif
1289
Howard Hinnant47499b12010-08-27 20:10:19 +00001290public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001291 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001292 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001293#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001294 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001295 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001296 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1297 future(const future&) = delete;
1298 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001300 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001301 {
1302 future(std::move(__rhs)).swap(*this);
1303 return *this;
1304 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001305#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001306private:
1307 future(const future&);
1308 future& operator=(const future&);
1309public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001310#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001311 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001312 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001313
1314 // retrieving the value
1315 void get();
1316
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001318 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001319
1320 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001322 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001323
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001324 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001325 void wait() const {__state_->wait();}
1326 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001328 future_status
1329 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1330 {return __state_->wait_for(__rel_time);}
1331 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001332 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001333 future_status
1334 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1335 {return __state_->wait_until(__abs_time);}
1336};
1337
Howard Hinnant99968442011-11-29 18:15:50 +00001338template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001339inline _LIBCPP_INLINE_VISIBILITY
1340void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001341swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00001342{
1343 __x.swap(__y);
1344}
1345
Howard Hinnant47499b12010-08-27 20:10:19 +00001346// promise<R>
1347
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001348template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001349
Howard Hinnant99968442011-11-29 18:15:50 +00001350template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001351class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001352{
Howard Hinnant99968442011-11-29 18:15:50 +00001353 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001354
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001355 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001356 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001357
1358 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001359public:
1360 promise();
1361 template <class _Alloc>
1362 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001363#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001364 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001365 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001366 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1367 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001368#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001369private:
1370 promise(const promise& __rhs);
1371public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001372#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001373 ~promise();
1374
1375 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001376#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001377 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001378 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001379 {
1380 promise(std::move(__rhs)).swap(*this);
1381 return *this;
1382 }
1383 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001384#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001385private:
1386 promise& operator=(const promise& __rhs);
1387public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001388#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001389 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001390 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001391
1392 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001393 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001394
1395 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001396 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001397#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001398 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001399#endif
1400 void set_exception(exception_ptr __p);
1401
1402 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001403 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001404#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001405 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001406#endif
1407 void set_exception_at_thread_exit(exception_ptr __p);
1408};
1409
Howard Hinnant99968442011-11-29 18:15:50 +00001410template <class _Rp>
1411promise<_Rp>::promise()
1412 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001413{
1414}
1415
Howard Hinnant99968442011-11-29 18:15:50 +00001416template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001417template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001418promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001419{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001420 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1421 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001422 typedef __allocator_destructor<_A2> _D2;
1423 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001424 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1425 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1426 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001427}
1428
Howard Hinnant99968442011-11-29 18:15:50 +00001429template <class _Rp>
1430promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001431{
1432 if (__state_)
1433 {
1434 if (!__state_->__has_value() && __state_->use_count() > 1)
1435 __state_->set_exception(make_exception_ptr(
1436 future_error(make_error_code(future_errc::broken_promise))
1437 ));
1438 __state_->__release_shared();
1439 }
1440}
1441
Howard Hinnant99968442011-11-29 18:15:50 +00001442template <class _Rp>
1443future<_Rp>
1444promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001445{
1446 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001447 __throw_future_error(future_errc::no_state);
Howard Hinnant99968442011-11-29 18:15:50 +00001448 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001449}
1450
Howard Hinnant99968442011-11-29 18:15:50 +00001451template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001452void
Howard Hinnant99968442011-11-29 18:15:50 +00001453promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001454{
1455 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001456 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001457 __state_->set_value(__r);
1458}
1459
Howard Hinnant73d21a42010-09-04 23:28:19 +00001460#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001461
Howard Hinnant99968442011-11-29 18:15:50 +00001462template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001463void
Howard Hinnant99968442011-11-29 18:15:50 +00001464promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001465{
1466 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001467 __throw_future_error(future_errc::no_state);
Howard Hinnant0949eed2011-06-30 21:18:19 +00001468 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001469}
1470
Howard Hinnant73d21a42010-09-04 23:28:19 +00001471#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001472
Howard Hinnant99968442011-11-29 18:15:50 +00001473template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001474void
Howard Hinnant99968442011-11-29 18:15:50 +00001475promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001476{
1477 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001478 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001479 __state_->set_exception(__p);
1480}
1481
Howard Hinnant99968442011-11-29 18:15:50 +00001482template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001483void
Howard Hinnant99968442011-11-29 18:15:50 +00001484promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001485{
1486 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001487 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001488 __state_->set_value_at_thread_exit(__r);
1489}
1490
Howard Hinnant73d21a42010-09-04 23:28:19 +00001491#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001492
Howard Hinnant99968442011-11-29 18:15:50 +00001493template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001494void
Howard Hinnant99968442011-11-29 18:15:50 +00001495promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001496{
1497 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001498 __throw_future_error(future_errc::no_state);
Howard Hinnant0949eed2011-06-30 21:18:19 +00001499 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001500}
1501
Howard Hinnant73d21a42010-09-04 23:28:19 +00001502#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001503
Howard Hinnant99968442011-11-29 18:15:50 +00001504template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001505void
Howard Hinnant99968442011-11-29 18:15:50 +00001506promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001507{
1508 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001509 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001510 __state_->set_exception_at_thread_exit(__p);
1511}
1512
1513// promise<R&>
1514
Howard Hinnant99968442011-11-29 18:15:50 +00001515template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001516class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001517{
Howard Hinnant99968442011-11-29 18:15:50 +00001518 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001519
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001520 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001521 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001522
1523 template <class> friend class packaged_task;
1524
Howard Hinnant47499b12010-08-27 20:10:19 +00001525public:
1526 promise();
1527 template <class _Allocator>
1528 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001529#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001531 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001532 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1533 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001534#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001535private:
1536 promise(const promise& __rhs);
1537public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001538#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001539 ~promise();
1540
1541 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001542#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001543 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001544 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001545 {
1546 promise(std::move(__rhs)).swap(*this);
1547 return *this;
1548 }
1549 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001550#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001551private:
1552 promise& operator=(const promise& __rhs);
1553public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001554#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001556 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001557
1558 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001559 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001560
1561 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001562 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001563 void set_exception(exception_ptr __p);
1564
1565 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001566 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001567 void set_exception_at_thread_exit(exception_ptr __p);
1568};
1569
Howard Hinnant99968442011-11-29 18:15:50 +00001570template <class _Rp>
1571promise<_Rp&>::promise()
1572 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001573{
1574}
1575
Howard Hinnant99968442011-11-29 18:15:50 +00001576template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001577template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001578promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001579{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001580 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1581 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001582 typedef __allocator_destructor<_A2> _D2;
1583 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001584 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1585 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1586 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001587}
1588
Howard Hinnant99968442011-11-29 18:15:50 +00001589template <class _Rp>
1590promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001591{
1592 if (__state_)
1593 {
1594 if (!__state_->__has_value() && __state_->use_count() > 1)
1595 __state_->set_exception(make_exception_ptr(
1596 future_error(make_error_code(future_errc::broken_promise))
1597 ));
1598 __state_->__release_shared();
1599 }
1600}
1601
Howard Hinnant99968442011-11-29 18:15:50 +00001602template <class _Rp>
1603future<_Rp&>
1604promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001605{
1606 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001607 __throw_future_error(future_errc::no_state);
Howard Hinnant99968442011-11-29 18:15:50 +00001608 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001609}
1610
Howard Hinnant99968442011-11-29 18:15:50 +00001611template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001612void
Howard Hinnant99968442011-11-29 18:15:50 +00001613promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001614{
1615 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001616 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001617 __state_->set_value(__r);
1618}
1619
Howard Hinnant99968442011-11-29 18:15:50 +00001620template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001621void
Howard Hinnant99968442011-11-29 18:15:50 +00001622promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001623{
1624 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001625 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001626 __state_->set_exception(__p);
1627}
1628
Howard Hinnant99968442011-11-29 18:15:50 +00001629template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001630void
Howard Hinnant99968442011-11-29 18:15:50 +00001631promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001632{
1633 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001634 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001635 __state_->set_value_at_thread_exit(__r);
1636}
1637
Howard Hinnant99968442011-11-29 18:15:50 +00001638template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001639void
Howard Hinnant99968442011-11-29 18:15:50 +00001640promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001641{
1642 if (__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00001643 __throw_future_error(future_errc::no_state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001644 __state_->set_exception_at_thread_exit(__p);
1645}
1646
1647// promise<void>
1648
1649template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001650class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001651{
1652 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001653
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001654 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001655 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001656
1657 template <class> friend class packaged_task;
1658
Howard Hinnant47499b12010-08-27 20:10:19 +00001659public:
1660 promise();
1661 template <class _Allocator>
1662 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001663#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001664 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001665 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001666 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1667 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001668#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001669private:
1670 promise(const promise& __rhs);
1671public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001672#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001673 ~promise();
1674
1675 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001676#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001678 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001679 {
1680 promise(std::move(__rhs)).swap(*this);
1681 return *this;
1682 }
1683 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001684#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001685private:
1686 promise& operator=(const promise& __rhs);
1687public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001688#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001689 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001690 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001691
1692 // retrieving the result
1693 future<void> get_future();
1694
1695 // setting the result
1696 void set_value();
1697 void set_exception(exception_ptr __p);
1698
1699 // setting the result with deferred notification
1700 void set_value_at_thread_exit();
1701 void set_exception_at_thread_exit(exception_ptr __p);
1702};
1703
1704template <class _Alloc>
1705promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1706{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001707 typedef __assoc_sub_state_alloc<_Alloc> _State;
1708 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001709 typedef __allocator_destructor<_A2> _D2;
1710 _A2 __a(__a0);
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001711 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1712 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1713 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant47499b12010-08-27 20:10:19 +00001714}
1715
Howard Hinnant99968442011-11-29 18:15:50 +00001716template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001717inline _LIBCPP_INLINE_VISIBILITY
1718void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001719swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001720{
1721 __x.swap(__y);
1722}
1723
Howard Hinnant99968442011-11-29 18:15:50 +00001724template <class _Rp, class _Alloc>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001725 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001726 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001727
Howard Hinnant54da3382010-08-30 18:46:21 +00001728#ifndef _LIBCPP_HAS_NO_VARIADICS
1729
1730// packaged_task
1731
1732template<class _Fp> class __packaged_task_base;
1733
Howard Hinnant99968442011-11-29 18:15:50 +00001734template<class _Rp, class ..._ArgTypes>
1735class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001736{
1737 __packaged_task_base(const __packaged_task_base&);
1738 __packaged_task_base& operator=(const __packaged_task_base&);
1739public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001740 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001741 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001743 virtual ~__packaged_task_base() {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001744 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001745 virtual void destroy() = 0;
1746 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001747 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001748};
1749
1750template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1751
Howard Hinnant99968442011-11-29 18:15:50 +00001752template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1753class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1754 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001755{
Howard Hinnant99968442011-11-29 18:15:50 +00001756 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001757public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001759 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001760 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001761 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001762 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001763 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001764 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001766 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001767 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001768 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001769 virtual void destroy();
1770 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001771 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001772};
1773
Howard Hinnant99968442011-11-29 18:15:50 +00001774template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001775void
Howard Hinnant99968442011-11-29 18:15:50 +00001776__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001777 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001778{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001779 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001780}
1781
Howard Hinnant99968442011-11-29 18:15:50 +00001782template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001783void
Howard Hinnant99968442011-11-29 18:15:50 +00001784__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001785{
Howard Hinnant99968442011-11-29 18:15:50 +00001786 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001787}
1788
Howard Hinnant99968442011-11-29 18:15:50 +00001789template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001790void
Howard Hinnant99968442011-11-29 18:15:50 +00001791__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001792{
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001793 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1794 typedef allocator_traits<_Ap> _ATraits;
1795 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnant99968442011-11-29 18:15:50 +00001796 _Ap __a(__f_.second());
1797 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001798 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant54da3382010-08-30 18:46:21 +00001799}
1800
Howard Hinnant99968442011-11-29 18:15:50 +00001801template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1802_Rp
1803__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001804{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001805 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001806}
1807
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001808template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001809
Howard Hinnant99968442011-11-29 18:15:50 +00001810template<class _Rp, class ..._ArgTypes>
1811class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001812{
Howard Hinnant99968442011-11-29 18:15:50 +00001813 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant78f0de22013-01-21 17:26:55 +00001814 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001815 __base* __f_;
1816
1817public:
Howard Hinnant99968442011-11-29 18:15:50 +00001818 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001819
1820 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001821 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001822 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001823 template<class _Fp>
1824 __packaged_task_function(_Fp&& __f);
1825 template<class _Fp, class _Alloc>
1826 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001827
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001828 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1829 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001830
1831 __packaged_task_function(const __packaged_task_function&) = delete;
1832 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1833
1834 ~__packaged_task_function();
1835
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001836 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001837
Howard Hinnant99968442011-11-29 18:15:50 +00001838 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001839};
1840
Howard Hinnant99968442011-11-29 18:15:50 +00001841template<class _Rp, class ..._ArgTypes>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001842__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001843{
1844 if (__f.__f_ == nullptr)
1845 __f_ = nullptr;
1846 else if (__f.__f_ == (__base*)&__f.__buf_)
1847 {
1848 __f_ = (__base*)&__buf_;
1849 __f.__f_->__move_to(__f_);
1850 }
1851 else
1852 {
1853 __f_ = __f.__f_;
1854 __f.__f_ = nullptr;
1855 }
1856}
1857
Howard Hinnant99968442011-11-29 18:15:50 +00001858template<class _Rp, class ..._ArgTypes>
1859template <class _Fp>
1860__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001861 : __f_(nullptr)
1862{
Marshall Clowf1264e72014-04-07 13:32:26 +00001863 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnant99968442011-11-29 18:15:50 +00001864 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001865 if (sizeof(_FF) <= sizeof(__buf_))
1866 {
1867 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001868 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001869 }
1870 else
1871 {
Howard Hinnant99968442011-11-29 18:15:50 +00001872 typedef allocator<_FF> _Ap;
1873 _Ap __a;
1874 typedef __allocator_destructor<_Ap> _Dp;
1875 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1876 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001877 __f_ = __hold.release();
1878 }
1879}
1880
Howard Hinnant99968442011-11-29 18:15:50 +00001881template<class _Rp, class ..._ArgTypes>
1882template <class _Fp, class _Alloc>
1883__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1884 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001885 : __f_(nullptr)
1886{
Marshall Clowf1264e72014-04-07 13:32:26 +00001887 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnant99968442011-11-29 18:15:50 +00001888 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001889 if (sizeof(_FF) <= sizeof(__buf_))
1890 {
1891 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001892 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001893 }
1894 else
1895 {
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001896 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnant99968442011-11-29 18:15:50 +00001897 _Ap __a(__a0);
1898 typedef __allocator_destructor<_Ap> _Dp;
1899 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier4d2413c2014-10-23 06:24:45 +00001900 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1901 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1902 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnant54da3382010-08-30 18:46:21 +00001903 }
1904}
1905
Howard Hinnant99968442011-11-29 18:15:50 +00001906template<class _Rp, class ..._ArgTypes>
1907__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001908__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001909{
1910 if (__f_ == (__base*)&__buf_)
1911 __f_->destroy();
1912 else if (__f_)
1913 __f_->destroy_deallocate();
1914 __f_ = nullptr;
1915 if (__f.__f_ == nullptr)
1916 __f_ = nullptr;
1917 else if (__f.__f_ == (__base*)&__f.__buf_)
1918 {
1919 __f_ = (__base*)&__buf_;
1920 __f.__f_->__move_to(__f_);
1921 }
1922 else
1923 {
1924 __f_ = __f.__f_;
1925 __f.__f_ = nullptr;
1926 }
Argyrios Kyrtzidis1dc6f7a2012-10-13 02:03:45 +00001927 return *this;
Howard Hinnant54da3382010-08-30 18:46:21 +00001928}
1929
Howard Hinnant99968442011-11-29 18:15:50 +00001930template<class _Rp, class ..._ArgTypes>
1931__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001932{
1933 if (__f_ == (__base*)&__buf_)
1934 __f_->destroy();
1935 else if (__f_)
1936 __f_->destroy_deallocate();
1937}
1938
Howard Hinnant99968442011-11-29 18:15:50 +00001939template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001940void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001941__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001942{
1943 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1944 {
1945 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1946 __base* __t = (__base*)&__tempbuf;
1947 __f_->__move_to(__t);
1948 __f_->destroy();
1949 __f_ = nullptr;
1950 __f.__f_->__move_to((__base*)&__buf_);
1951 __f.__f_->destroy();
1952 __f.__f_ = nullptr;
1953 __f_ = (__base*)&__buf_;
1954 __t->__move_to((__base*)&__f.__buf_);
1955 __t->destroy();
1956 __f.__f_ = (__base*)&__f.__buf_;
1957 }
1958 else if (__f_ == (__base*)&__buf_)
1959 {
1960 __f_->__move_to((__base*)&__f.__buf_);
1961 __f_->destroy();
1962 __f_ = __f.__f_;
1963 __f.__f_ = (__base*)&__f.__buf_;
1964 }
1965 else if (__f.__f_ == (__base*)&__f.__buf_)
1966 {
1967 __f.__f_->__move_to((__base*)&__buf_);
1968 __f.__f_->destroy();
1969 __f.__f_ = __f_;
1970 __f_ = (__base*)&__buf_;
1971 }
1972 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001973 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001974}
1975
Howard Hinnant99968442011-11-29 18:15:50 +00001976template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001977inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001978_Rp
1979__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00001980{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001981 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001982}
1983
Howard Hinnant99968442011-11-29 18:15:50 +00001984template<class _Rp, class ..._ArgTypes>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00001985class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001986{
1987public:
Howard Hinnant99968442011-11-29 18:15:50 +00001988 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001989
1990private:
1991 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1992 promise<result_type> __p_;
1993
1994public:
1995 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001996 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001997 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00001998 template <class _Fp,
1999 class = typename enable_if
2000 <
2001 !is_same<
2002 typename decay<_Fp>::type,
2003 packaged_task
2004 >::value
2005 >::type
2006 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002007 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002008 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002009 template <class _Fp, class _Allocator,
2010 class = typename enable_if
2011 <
2012 !is_same<
2013 typename decay<_Fp>::type,
2014 packaged_task
2015 >::value
2016 >::type
2017 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002018 _LIBCPP_INLINE_VISIBILITY
Marshall Clow07546f32015-06-30 14:16:49 +00002019 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnant99968442011-11-29 18:15:50 +00002020 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002021 __p_(allocator_arg, __a) {}
2022 // ~packaged_task() = default;
2023
2024 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002025 packaged_task(const packaged_task&) = delete;
2026 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002027
2028 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002029 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002030 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002031 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002032 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002033 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002034 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002035 __f_ = _VSTD::move(__other.__f_);
2036 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002037 return *this;
2038 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002039 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002040 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002041 {
2042 __f_.swap(__other.__f_);
2043 __p_.swap(__other.__p_);
2044 }
2045
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002046 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002047 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002048
2049 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002050 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002051 future<result_type> get_future() {return __p_.get_future();}
2052
2053 // execution
2054 void operator()(_ArgTypes... __args);
2055 void make_ready_at_thread_exit(_ArgTypes... __args);
2056
2057 void reset();
2058};
2059
Howard Hinnant99968442011-11-29 18:15:50 +00002060template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002061void
Howard Hinnant99968442011-11-29 18:15:50 +00002062packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002063{
Howard Hinnant54da3382010-08-30 18:46:21 +00002064 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002065 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002066 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002067 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002068#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002069 try
2070 {
2071#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002072 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002073#ifndef _LIBCPP_NO_EXCEPTIONS
2074 }
2075 catch (...)
2076 {
2077 __p_.set_exception(current_exception());
2078 }
2079#endif // _LIBCPP_NO_EXCEPTIONS
2080}
2081
Howard Hinnant99968442011-11-29 18:15:50 +00002082template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002083void
Howard Hinnant99968442011-11-29 18:15:50 +00002084packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002085{
Howard Hinnant54da3382010-08-30 18:46:21 +00002086 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002087 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002088 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002089 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002090#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002091 try
2092 {
2093#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002094 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002095#ifndef _LIBCPP_NO_EXCEPTIONS
2096 }
2097 catch (...)
2098 {
2099 __p_.set_exception_at_thread_exit(current_exception());
2100 }
2101#endif // _LIBCPP_NO_EXCEPTIONS
2102}
2103
Howard Hinnant99968442011-11-29 18:15:50 +00002104template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002105void
Howard Hinnant99968442011-11-29 18:15:50 +00002106packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002107{
Howard Hinnant7de47902010-11-30 20:23:32 +00002108 if (!valid())
Eric Fiselier423ca202015-10-02 21:25:15 +00002109 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002110 __p_ = promise<result_type>();
2111}
2112
2113template<class ..._ArgTypes>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002114class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002115{
2116public:
2117 typedef void result_type;
2118
2119private:
2120 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2121 promise<result_type> __p_;
2122
2123public:
2124 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002125 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002126 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002127 template <class _Fp,
2128 class = typename enable_if
2129 <
2130 !is_same<
2131 typename decay<_Fp>::type,
2132 packaged_task
2133 >::value
2134 >::type
2135 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002137 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow5f2d5b92013-10-12 22:49:17 +00002138 template <class _Fp, class _Allocator,
2139 class = typename enable_if
2140 <
2141 !is_same<
2142 typename decay<_Fp>::type,
2143 packaged_task
2144 >::value
2145 >::type
2146 >
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002147 _LIBCPP_INLINE_VISIBILITY
Marshall Clow5706c372015-06-30 18:28:35 +00002148 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnant99968442011-11-29 18:15:50 +00002149 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002150 __p_(allocator_arg, __a) {}
2151 // ~packaged_task() = default;
2152
2153 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002154 packaged_task(const packaged_task&) = delete;
2155 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002156
2157 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002158 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002159 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002160 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002161 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002162 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002163 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002164 __f_ = _VSTD::move(__other.__f_);
2165 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002166 return *this;
2167 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002168 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002169 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002170 {
2171 __f_.swap(__other.__f_);
2172 __p_.swap(__other.__p_);
2173 }
2174
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002175 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002176 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002177
2178 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002179 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002180 future<result_type> get_future() {return __p_.get_future();}
2181
2182 // execution
2183 void operator()(_ArgTypes... __args);
2184 void make_ready_at_thread_exit(_ArgTypes... __args);
2185
2186 void reset();
2187};
2188
2189template<class ..._ArgTypes>
2190void
2191packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2192{
Howard Hinnant54da3382010-08-30 18:46:21 +00002193 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002194 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002195 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002196 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002197#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002198 try
2199 {
2200#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002201 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002202 __p_.set_value();
2203#ifndef _LIBCPP_NO_EXCEPTIONS
2204 }
2205 catch (...)
2206 {
2207 __p_.set_exception(current_exception());
2208 }
2209#endif // _LIBCPP_NO_EXCEPTIONS
2210}
2211
2212template<class ..._ArgTypes>
2213void
2214packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2215{
Howard Hinnant54da3382010-08-30 18:46:21 +00002216 if (__p_.__state_ == nullptr)
Eric Fiselier423ca202015-10-02 21:25:15 +00002217 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002218 if (__p_.__state_->__has_value())
Eric Fiselier423ca202015-10-02 21:25:15 +00002219 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clowa1899742015-09-03 15:11:32 +00002220#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant54da3382010-08-30 18:46:21 +00002221 try
2222 {
2223#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002224 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002225 __p_.set_value_at_thread_exit();
2226#ifndef _LIBCPP_NO_EXCEPTIONS
2227 }
2228 catch (...)
2229 {
2230 __p_.set_exception_at_thread_exit(current_exception());
2231 }
2232#endif // _LIBCPP_NO_EXCEPTIONS
2233}
2234
2235template<class ..._ArgTypes>
2236void
2237packaged_task<void(_ArgTypes...)>::reset()
2238{
Howard Hinnant7de47902010-11-30 20:23:32 +00002239 if (!valid())
Eric Fiselier423ca202015-10-02 21:25:15 +00002240 __throw_future_error(future_errc::no_state);
Howard Hinnant54da3382010-08-30 18:46:21 +00002241 __p_ = promise<result_type>();
2242}
2243
2244template <class _Callable>
2245inline _LIBCPP_INLINE_VISIBILITY
2246void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002247swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002248{
2249 __x.swap(__y);
2250}
2251
2252template <class _Callable, class _Alloc>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002253struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002254 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002255
Howard Hinnant99968442011-11-29 18:15:50 +00002256template <class _Rp, class _Fp>
2257future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002258#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002259__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002260#else
Howard Hinnant99968442011-11-29 18:15:50 +00002261__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002262#endif
2263{
Howard Hinnant99968442011-11-29 18:15:50 +00002264 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2265 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2266 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002267}
2268
Howard Hinnant99968442011-11-29 18:15:50 +00002269template <class _Rp, class _Fp>
2270future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002271#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002272__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002273#else
Howard Hinnant99968442011-11-29 18:15:50 +00002274__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002275#endif
2276{
Howard Hinnant99968442011-11-29 18:15:50 +00002277 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2278 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2279 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2280 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002281}
2282
Howard Hinnant99968442011-11-29 18:15:50 +00002283template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002284class __async_func
2285{
Howard Hinnant99968442011-11-29 18:15:50 +00002286 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002287
2288public:
Howard Hinnant99968442011-11-29 18:15:50 +00002289 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002290
2291 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002292 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002293 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002294
2295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002296 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002297
Howard Hinnant99968442011-11-29 18:15:50 +00002298 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002299 {
2300 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2301 return __execute(_Index());
2302 }
2303private:
2304 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002305 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002306 __execute(__tuple_indices<_Indices...>)
2307 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002308 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002309 }
2310};
2311
Marshall Clow3b3108e2013-11-03 22:06:53 +00002312inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clowad2a6002013-11-03 15:43:35 +00002313{ return (int(__policy) & int(__value)) != 0; }
2314
Howard Hinnant99968442011-11-29 18:15:50 +00002315template <class _Fp, class... _Args>
2316future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2317async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002318{
Howard Hinnant99968442011-11-29 18:15:50 +00002319 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2320 typedef typename _BF::_Rp _Rp;
Marshall Clowad2a6002013-11-03 15:43:35 +00002321
2322#ifndef _LIBCPP_NO_EXCEPTIONS
2323 try
2324 {
2325#endif
2326 if (__does_policy_contain(__policy, launch::async))
2327 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002328 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clowad2a6002013-11-03 15:43:35 +00002329#ifndef _LIBCPP_NO_EXCEPTIONS
2330 }
2331 catch ( ... ) { if (__policy == launch::async) throw ; }
2332#endif
2333
2334 if (__does_policy_contain(__policy, launch::deferred))
2335 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002336 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clowad2a6002013-11-03 15:43:35 +00002337 return future<_Rp>{};
Howard Hinnant54da3382010-08-30 18:46:21 +00002338}
2339
Howard Hinnant99968442011-11-29 18:15:50 +00002340template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002341inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002342future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2343async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002344{
Howard Hinnant99968442011-11-29 18:15:50 +00002345 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002346 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002347}
2348
2349#endif // _LIBCPP_HAS_NO_VARIADICS
2350
Howard Hinnante6e4d012010-09-03 21:46:37 +00002351// shared_future
2352
Howard Hinnant99968442011-11-29 18:15:50 +00002353template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002354class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002355{
Howard Hinnant99968442011-11-29 18:15:50 +00002356 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002357
2358public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002359 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002360 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002361 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002362 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2363 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002364#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002366 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002367 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002369 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002370 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002371#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002372 ~shared_future();
2373 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002374#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002376 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002377 {
2378 shared_future(std::move(__rhs)).swap(*this);
2379 return *this;
2380 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002381#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002382
2383 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002385 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002386
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002388 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002389
2390 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002392 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002393
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002395 void wait() const {__state_->wait();}
2396 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002397 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002398 future_status
2399 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2400 {return __state_->wait_for(__rel_time);}
2401 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002403 future_status
2404 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2405 {return __state_->wait_until(__abs_time);}
2406};
2407
Howard Hinnant99968442011-11-29 18:15:50 +00002408template <class _Rp>
2409shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002410{
2411 if (__state_)
2412 __state_->__release_shared();
2413}
2414
Howard Hinnant99968442011-11-29 18:15:50 +00002415template <class _Rp>
2416shared_future<_Rp>&
2417shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002418{
2419 if (__rhs.__state_)
2420 __rhs.__state_->__add_shared();
2421 if (__state_)
2422 __state_->__release_shared();
2423 __state_ = __rhs.__state_;
2424 return *this;
2425}
2426
Howard Hinnant99968442011-11-29 18:15:50 +00002427template <class _Rp>
Howard Hinnant0f678bd2013-08-12 18:38:34 +00002428class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002429{
Howard Hinnant99968442011-11-29 18:15:50 +00002430 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002431
2432public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002434 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002436 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2437 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002438#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002440 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002441 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002442 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002443 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002444 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002445#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002446 ~shared_future();
2447 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002448#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002449 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002450 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002451 {
2452 shared_future(std::move(__rhs)).swap(*this);
2453 return *this;
2454 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002455#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002456
2457 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002459 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002460
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002461 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002462 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002463
2464 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002466 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002467
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002469 void wait() const {__state_->wait();}
2470 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002472 future_status
2473 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2474 {return __state_->wait_for(__rel_time);}
2475 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002477 future_status
2478 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2479 {return __state_->wait_until(__abs_time);}
2480};
2481
Howard Hinnant99968442011-11-29 18:15:50 +00002482template <class _Rp>
2483shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002484{
2485 if (__state_)
2486 __state_->__release_shared();
2487}
2488
Howard Hinnant99968442011-11-29 18:15:50 +00002489template <class _Rp>
2490shared_future<_Rp&>&
2491shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002492{
2493 if (__rhs.__state_)
2494 __rhs.__state_->__add_shared();
2495 if (__state_)
2496 __state_->__release_shared();
2497 __state_ = __rhs.__state_;
2498 return *this;
2499}
2500
2501template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00002502class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002503{
2504 __assoc_sub_state* __state_;
2505
2506public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002507 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002508 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002509 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002510 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2511 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002512#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002513 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002514 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002515 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002516 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002517 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002518 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002519#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002520 ~shared_future();
2521 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002522#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002523 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002524 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002525 {
2526 shared_future(std::move(__rhs)).swap(*this);
2527 return *this;
2528 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002529#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002530
2531 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002533 void get() const {__state_->copy();}
2534
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002536 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002537
2538 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002540 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002541
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002543 void wait() const {__state_->wait();}
2544 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002545 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002546 future_status
2547 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2548 {return __state_->wait_for(__rel_time);}
2549 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002551 future_status
2552 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2553 {return __state_->wait_until(__abs_time);}
2554};
2555
Howard Hinnant99968442011-11-29 18:15:50 +00002556template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002557inline _LIBCPP_INLINE_VISIBILITY
2558void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002559swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002560{
2561 __x.swap(__y);
2562}
2563
Howard Hinnant99968442011-11-29 18:15:50 +00002564template <class _Rp>
Howard Hinnant7de47902010-11-30 20:23:32 +00002565inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002566shared_future<_Rp>
2567future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002568{
Howard Hinnant99968442011-11-29 18:15:50 +00002569 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002570}
2571
Howard Hinnant99968442011-11-29 18:15:50 +00002572template <class _Rp>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002573inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002574shared_future<_Rp&>
2575future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002576{
Howard Hinnant99968442011-11-29 18:15:50 +00002577 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002578}
2579
Howard Hinnanta4451512010-12-02 16:45:21 +00002580#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2581
Howard Hinnant7de47902010-11-30 20:23:32 +00002582inline _LIBCPP_INLINE_VISIBILITY
2583shared_future<void>
2584future<void>::share()
2585{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002586 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002587}
2588
Howard Hinnanta4451512010-12-02 16:45:21 +00002589#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2590
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002591_LIBCPP_END_NAMESPACE_STD
2592
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +00002593#endif // !_LIBCPP_HAS_NO_THREADS
2594
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002595#endif // _LIBCPP_FUTURE