blob: 0f8fe57da20a64eede2a53ed0933c5e23aa8a2b7 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
Howard Hinnantee11c312010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc51e1022010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000022 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000023 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000024 no_state,
25 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000026};
27
28enum class launch
29{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000033};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000045
Howard Hinnant22448042012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
Howard Hinnant22448042012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000056};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000073
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
Howard Hinnant22448042012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
Howard Hinnant22448042012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
Howard Hinnant22448042012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
Howard Hinnant22448042012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
Howard Hinnant22448042012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
Howard Hinnant22448042012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
Howard Hinnant22448042012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantc51e1022010-05-11 19:42:16 +0000311template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000312 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000316 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantc566dc32010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
325 typedef R result_type;
326
327 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
Marshall Clowc317e022015-06-30 14:16:49 +0000332 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000333 ~packaged_task();
334
335 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000340 packaged_task(packaged_task&& other) noexcept;
341 packaged_task& operator=(packaged_task&& other) noexcept;
342 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000343
Howard Hinnant22448042012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000358
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000375#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000377#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000378#error <future> is not supported on this single threaded system
379#else // !_LIBCPP_HAS_NO_THREADS
380
Howard Hinnantc51e1022010-05-11 19:42:16 +0000381_LIBCPP_BEGIN_NAMESPACE_STD
382
383//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000384_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000385{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000386 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000388 no_state,
389 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000391_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000392
Howard Hinnant684902d2010-09-22 14:16:26 +0000393template <>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000394struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000395
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000396#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397template <>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000398struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000399#endif
400
Howard Hinnantc51e1022010-05-11 19:42:16 +0000401//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000402_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000403{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000404 async = 1,
405 deferred = 2,
406 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000409
Howard Hinnantda760a82013-06-29 18:38:17 +0000410#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411
412#ifdef _LIBCXX_UNDERLYING_TYPE
413typedef underlying_type<launch>::type __launch_underlying_type;
414#else
415typedef int __launch_underlying_type;
416#endif
417
418inline _LIBCPP_INLINE_VISIBILITY
419_LIBCPP_CONSTEXPR
420launch
421operator&(launch __x, launch __y)
422{
423 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
424 static_cast<__launch_underlying_type>(__y));
425}
426
427inline _LIBCPP_INLINE_VISIBILITY
428_LIBCPP_CONSTEXPR
429launch
430operator|(launch __x, launch __y)
431{
432 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
433 static_cast<__launch_underlying_type>(__y));
434}
435
436inline _LIBCPP_INLINE_VISIBILITY
437_LIBCPP_CONSTEXPR
438launch
439operator^(launch __x, launch __y)
440{
441 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
442 static_cast<__launch_underlying_type>(__y));
443}
444
445inline _LIBCPP_INLINE_VISIBILITY
446_LIBCPP_CONSTEXPR
447launch
448operator~(launch __x)
449{
Howard Hinnant373d7602013-07-02 18:01:41 +0000450 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000451}
452
453inline _LIBCPP_INLINE_VISIBILITY
454launch&
455operator&=(launch& __x, launch __y)
456{
457 __x = __x & __y; return __x;
458}
459
460inline _LIBCPP_INLINE_VISIBILITY
461launch&
462operator|=(launch& __x, launch __y)
463{
464 __x = __x | __y; return __x;
465}
466
467inline _LIBCPP_INLINE_VISIBILITY
468launch&
469operator^=(launch& __x, launch __y)
470{
471 __x = __x ^ __y; return __x;
472}
473
474#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
475
Howard Hinnantc51e1022010-05-11 19:42:16 +0000476//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000477_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000478{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479 ready,
480 timeout,
481 deferred
482};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000483_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000484
Howard Hinnant8331b762013-03-06 23:30:19 +0000485_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000486const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000487
488inline _LIBCPP_INLINE_VISIBILITY
489error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000490make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000491{
492 return error_code(static_cast<int>(__e), future_category());
493}
494
495inline _LIBCPP_INLINE_VISIBILITY
496error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000497make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000498{
499 return error_condition(static_cast<int>(__e), future_category());
500}
501
Howard Hinnant684902d2010-09-22 14:16:26 +0000502class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000503 : public logic_error
504{
505 error_code __ec_;
506public:
507 future_error(error_code __ec);
508
Howard Hinnant684902d2010-09-22 14:16:26 +0000509 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000510 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000511
512 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000513};
514
Marshall Clow7b3742d2015-09-03 15:11:32 +0000515template <future_errc _Ev>
516_LIBCPP_ALWAYS_INLINE
517void __throw_future_error()
518{
519#ifndef _LIBCPP_NO_EXCEPTIONS
520 throw future_error(make_error_code(_Ev));
521#else
522 assert(!"future_error");
523#endif
524}
525
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000526class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000527 : public __shared_count
528{
529protected:
530 exception_ptr __exception_;
531 mutable mutex __mut_;
532 mutable condition_variable __cv_;
533 unsigned __state_;
534
Howard Hinnant719bda32011-05-28 14:41:13 +0000535 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000536 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000537public:
538 enum
539 {
540 __constructed = 1,
541 __future_attached = 2,
542 ready = 4,
543 deferred = 8
544 };
545
Howard Hinnant684902d2010-09-22 14:16:26 +0000546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000547 __assoc_sub_state() : __state_(0) {}
548
Howard Hinnant684902d2010-09-22 14:16:26 +0000549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000550 bool __has_value() const
551 {return (__state_ & __constructed) || (__exception_ != nullptr);}
552
Howard Hinnant684902d2010-09-22 14:16:26 +0000553 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante667ecc2013-01-14 20:01:24 +0000554 void __set_future_attached()
555 {
556 lock_guard<mutex> __lk(__mut_);
557 __state_ |= __future_attached;
558 }
Howard Hinnant684902d2010-09-22 14:16:26 +0000559 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000560 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000561
Howard Hinnant684902d2010-09-22 14:16:26 +0000562 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000563 void __set_deferred() {__state_ |= deferred;}
564
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000565 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000566 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000567 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000568
569 void set_value();
570 void set_value_at_thread_exit();
571
572 void set_exception(exception_ptr __p);
573 void set_exception_at_thread_exit(exception_ptr __p);
574
575 void copy();
576
Howard Hinnantccdd2032010-08-30 18:46:21 +0000577 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000578 template <class _Rep, class _Period>
579 future_status
580 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
581 template <class _Clock, class _Duration>
582 future_status
583 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000584
585 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000586};
587
Howard Hinnantf4712b92010-08-28 21:01:06 +0000588template <class _Clock, class _Duration>
589future_status
590__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
591{
592 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000593 if (__state_ & deferred)
594 return future_status::deferred;
595 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000596 __cv_.wait_until(__lk, __abs_time);
597 if (__state_ & ready)
598 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000599 return future_status::timeout;
600}
601
602template <class _Rep, class _Period>
603inline _LIBCPP_INLINE_VISIBILITY
604future_status
605__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
606{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000607 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000608}
609
Howard Hinnantc834c512011-11-29 18:15:50 +0000610template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000611class __assoc_state
612 : public __assoc_sub_state
613{
614 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000615 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000616protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000617 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000618
Howard Hinnant719bda32011-05-28 14:41:13 +0000619 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620public:
621
622 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000623#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000624 void set_value(_Arg&& __arg);
625#else
626 void set_value(_Arg& __arg);
627#endif
628
629 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000630#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000631 void set_value_at_thread_exit(_Arg&& __arg);
632#else
633 void set_value_at_thread_exit(_Arg& __arg);
634#endif
635
Howard Hinnantc834c512011-11-29 18:15:50 +0000636 _Rp move();
637 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000638};
639
Howard Hinnantc834c512011-11-29 18:15:50 +0000640template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000641void
Howard Hinnantc834c512011-11-29 18:15:50 +0000642__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000643{
644 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000645 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000646 delete this;
647}
648
Howard Hinnantc834c512011-11-29 18:15:50 +0000649template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000650template <class _Arg>
651void
Howard Hinnant74279a52010-09-04 23:28:19 +0000652#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000653__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000654#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000655__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000656#endif
657{
658 unique_lock<mutex> __lk(this->__mut_);
659 if (this->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +0000660 __throw_future_error<future_errc::promise_already_satisfied>();
Howard Hinnantc834c512011-11-29 18:15:50 +0000661 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000662 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000663 __cv_.notify_all();
664}
665
Howard Hinnantc834c512011-11-29 18:15:50 +0000666template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000667template <class _Arg>
668void
Howard Hinnant74279a52010-09-04 23:28:19 +0000669#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000670__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000671#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000672__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000673#endif
674{
675 unique_lock<mutex> __lk(this->__mut_);
676 if (this->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +0000677 __throw_future_error<future_errc::promise_already_satisfied>();
Howard Hinnantc834c512011-11-29 18:15:50 +0000678 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000679 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000680 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000681}
682
Howard Hinnantc834c512011-11-29 18:15:50 +0000683template <class _Rp>
684_Rp
685__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000686{
687 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000688 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000689 if (this->__exception_ != nullptr)
690 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000691 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000692}
693
Howard Hinnantc834c512011-11-29 18:15:50 +0000694template <class _Rp>
695typename add_lvalue_reference<_Rp>::type
696__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000697{
698 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000699 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000700 if (this->__exception_ != nullptr)
701 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000702 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000703}
704
Howard Hinnantc834c512011-11-29 18:15:50 +0000705template <class _Rp>
706class __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000707 : public __assoc_sub_state
708{
709 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000710 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000711protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000712 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000713
Howard Hinnant719bda32011-05-28 14:41:13 +0000714 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715public:
716
Howard Hinnantc834c512011-11-29 18:15:50 +0000717 void set_value(_Rp& __arg);
718 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000719
Howard Hinnantc834c512011-11-29 18:15:50 +0000720 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000721};
722
Howard Hinnantc834c512011-11-29 18:15:50 +0000723template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000724void
Howard Hinnantc834c512011-11-29 18:15:50 +0000725__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000726{
727 delete this;
728}
729
Howard Hinnantc834c512011-11-29 18:15:50 +0000730template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000731void
Howard Hinnantc834c512011-11-29 18:15:50 +0000732__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000733{
734 unique_lock<mutex> __lk(this->__mut_);
735 if (this->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +0000736 __throw_future_error<future_errc::promise_already_satisfied>();
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000737 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000738 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000739 __cv_.notify_all();
740}
741
Howard Hinnantc834c512011-11-29 18:15:50 +0000742template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743void
Howard Hinnantc834c512011-11-29 18:15:50 +0000744__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000745{
746 unique_lock<mutex> __lk(this->__mut_);
747 if (this->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +0000748 __throw_future_error<future_errc::promise_already_satisfied>();
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000749 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000750 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000751 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000752}
753
Howard Hinnantc834c512011-11-29 18:15:50 +0000754template <class _Rp>
755_Rp&
756__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000757{
758 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000759 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000760 if (this->__exception_ != nullptr)
761 rethrow_exception(this->__exception_);
762 return *__value_;
763}
764
Howard Hinnantc834c512011-11-29 18:15:50 +0000765template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000766class __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000767 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000768{
Howard Hinnantc834c512011-11-29 18:15:50 +0000769 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000770 _Alloc __alloc_;
771
Howard Hinnant719bda32011-05-28 14:41:13 +0000772 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000773public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000775 explicit __assoc_state_alloc(const _Alloc& __a)
776 : __alloc_(__a) {}
777};
778
Howard Hinnantc834c512011-11-29 18:15:50 +0000779template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000780void
Howard Hinnantc834c512011-11-29 18:15:50 +0000781__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000782{
783 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000784 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000785 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
786 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000787 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000788 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000789 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000790 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000791}
792
Howard Hinnantc834c512011-11-29 18:15:50 +0000793template <class _Rp, class _Alloc>
794class __assoc_state_alloc<_Rp&, _Alloc>
795 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000796{
Howard Hinnantc834c512011-11-29 18:15:50 +0000797 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000798 _Alloc __alloc_;
799
Howard Hinnant719bda32011-05-28 14:41:13 +0000800 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000801public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000802 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000803 explicit __assoc_state_alloc(const _Alloc& __a)
804 : __alloc_(__a) {}
805};
806
Howard Hinnantc834c512011-11-29 18:15:50 +0000807template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000808void
Howard Hinnantc834c512011-11-29 18:15:50 +0000809__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000810{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000811 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
812 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000813 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000814 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000815 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000816 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000817}
818
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000819template <class _Alloc>
820class __assoc_sub_state_alloc
821 : public __assoc_sub_state
822{
823 typedef __assoc_sub_state base;
824 _Alloc __alloc_;
825
Howard Hinnant719bda32011-05-28 14:41:13 +0000826 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000827public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000828 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000829 explicit __assoc_sub_state_alloc(const _Alloc& __a)
830 : __alloc_(__a) {}
831};
832
833template <class _Alloc>
834void
Howard Hinnant719bda32011-05-28 14:41:13 +0000835__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000836{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000837 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
838 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000839 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000840 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000841 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000842 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000843}
844
Howard Hinnantc834c512011-11-29 18:15:50 +0000845template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000846class __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000847 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000848{
Howard Hinnantc834c512011-11-29 18:15:50 +0000849 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000850
Howard Hinnantc834c512011-11-29 18:15:50 +0000851 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000852
853public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000854#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000855 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000856#endif
857
858 virtual void __execute();
859};
860
Howard Hinnant74279a52010-09-04 23:28:19 +0000861#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000862
Howard Hinnantc834c512011-11-29 18:15:50 +0000863template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000864inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000865__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
866 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000867{
868 this->__set_deferred();
869}
870
Howard Hinnant74279a52010-09-04 23:28:19 +0000871#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000872
Howard Hinnantc834c512011-11-29 18:15:50 +0000873template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000874void
Howard Hinnantc834c512011-11-29 18:15:50 +0000875__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000876{
877#ifndef _LIBCPP_NO_EXCEPTIONS
878 try
879 {
880#endif // _LIBCPP_NO_EXCEPTIONS
881 this->set_value(__func_());
882#ifndef _LIBCPP_NO_EXCEPTIONS
883 }
884 catch (...)
885 {
886 this->set_exception(current_exception());
887 }
888#endif // _LIBCPP_NO_EXCEPTIONS
889}
890
Howard Hinnantc834c512011-11-29 18:15:50 +0000891template <class _Fp>
892class __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000893 : public __assoc_sub_state
894{
895 typedef __assoc_sub_state base;
896
Howard Hinnantc834c512011-11-29 18:15:50 +0000897 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000898
899public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000900#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000901 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000902#endif
903
904 virtual void __execute();
905};
906
Howard Hinnant74279a52010-09-04 23:28:19 +0000907#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000908
Howard Hinnantc834c512011-11-29 18:15:50 +0000909template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000910inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000911__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
912 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000913{
914 this->__set_deferred();
915}
916
Howard Hinnant74279a52010-09-04 23:28:19 +0000917#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000918
Howard Hinnantc834c512011-11-29 18:15:50 +0000919template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000920void
Howard Hinnantc834c512011-11-29 18:15:50 +0000921__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000922{
923#ifndef _LIBCPP_NO_EXCEPTIONS
924 try
925 {
926#endif // _LIBCPP_NO_EXCEPTIONS
927 __func_();
928 this->set_value();
929#ifndef _LIBCPP_NO_EXCEPTIONS
930 }
931 catch (...)
932 {
933 this->set_exception(current_exception());
934 }
935#endif // _LIBCPP_NO_EXCEPTIONS
936}
937
Howard Hinnantc834c512011-11-29 18:15:50 +0000938template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000939class __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000940 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000941{
Howard Hinnantc834c512011-11-29 18:15:50 +0000942 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000943
Howard Hinnantc834c512011-11-29 18:15:50 +0000944 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000945
Howard Hinnant719bda32011-05-28 14:41:13 +0000946 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000947public:
948#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000949 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000950#endif
951
952 virtual void __execute();
953};
954
955#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
956
Howard Hinnantc834c512011-11-29 18:15:50 +0000957template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000958inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000959__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
960 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000961{
962}
963
964#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
965
Howard Hinnantc834c512011-11-29 18:15:50 +0000966template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000967void
Howard Hinnantc834c512011-11-29 18:15:50 +0000968__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000969{
970#ifndef _LIBCPP_NO_EXCEPTIONS
971 try
972 {
973#endif // _LIBCPP_NO_EXCEPTIONS
974 this->set_value(__func_());
975#ifndef _LIBCPP_NO_EXCEPTIONS
976 }
977 catch (...)
978 {
979 this->set_exception(current_exception());
980 }
981#endif // _LIBCPP_NO_EXCEPTIONS
982}
983
Howard Hinnantc834c512011-11-29 18:15:50 +0000984template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000985void
Howard Hinnantc834c512011-11-29 18:15:50 +0000986__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000987{
988 this->wait();
989 base::__on_zero_shared();
990}
991
Howard Hinnantc834c512011-11-29 18:15:50 +0000992template <class _Fp>
993class __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000994 : public __assoc_sub_state
995{
996 typedef __assoc_sub_state base;
997
Howard Hinnantc834c512011-11-29 18:15:50 +0000998 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000999
Howard Hinnant719bda32011-05-28 14:41:13 +00001000 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001001public:
1002#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001003 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001004#endif
1005
1006 virtual void __execute();
1007};
1008
1009#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1010
Howard Hinnantc834c512011-11-29 18:15:50 +00001011template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001012inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001013__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1014 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001015{
1016}
1017
1018#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1019
Howard Hinnantc834c512011-11-29 18:15:50 +00001020template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001021void
Howard Hinnantc834c512011-11-29 18:15:50 +00001022__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001023{
1024#ifndef _LIBCPP_NO_EXCEPTIONS
1025 try
1026 {
1027#endif // _LIBCPP_NO_EXCEPTIONS
1028 __func_();
1029 this->set_value();
1030#ifndef _LIBCPP_NO_EXCEPTIONS
1031 }
1032 catch (...)
1033 {
1034 this->set_exception(current_exception());
1035 }
1036#endif // _LIBCPP_NO_EXCEPTIONS
1037}
1038
Howard Hinnantc834c512011-11-29 18:15:50 +00001039template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001040void
Howard Hinnantc834c512011-11-29 18:15:50 +00001041__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001042{
1043 this->wait();
1044 base::__on_zero_shared();
1045}
1046
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001047template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1048template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001049
1050// future
1051
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001052template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001053
Howard Hinnantc834c512011-11-29 18:15:50 +00001054template <class _Rp, class _Fp>
1055future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001056#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001057__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001058#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001059__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001060#endif
1061
Howard Hinnantc834c512011-11-29 18:15:50 +00001062template <class _Rp, class _Fp>
1063future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001064#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001065__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001066#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001067__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001068#endif
1069
Howard Hinnantc834c512011-11-29 18:15:50 +00001070template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001071class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001072{
Howard Hinnantc834c512011-11-29 18:15:50 +00001073 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001074
Howard Hinnantc834c512011-11-29 18:15:50 +00001075 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001076
1077 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001078 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001079
Howard Hinnant74279a52010-09-04 23:28:19 +00001080#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001081 template <class _R1, class _Fp>
1082 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1083 template <class _R1, class _Fp>
1084 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001085#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001086 template <class _R1, class _Fp>
1087 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1088 template <class _R1, class _Fp>
1089 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001090#endif
1091
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001092public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001093 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001094 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001095#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001096 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001097 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001098 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1099 future(const future&) = delete;
1100 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001101 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001102 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001103 {
1104 future(std::move(__rhs)).swap(*this);
1105 return *this;
1106 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001107#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001108private:
1109 future(const future&);
1110 future& operator=(const future&);
1111public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001112#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001113 ~future();
Howard Hinnantc834c512011-11-29 18:15:50 +00001114 shared_future<_Rp> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001115
1116 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001117 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001118
Howard Hinnant684902d2010-09-22 14:16:26 +00001119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001120 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001121
1122 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001123 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001124 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001125
Howard Hinnant684902d2010-09-22 14:16:26 +00001126 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001127 void wait() const {__state_->wait();}
1128 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001129 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001130 future_status
1131 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1132 {return __state_->wait_for(__rel_time);}
1133 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001134 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001135 future_status
1136 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1137 {return __state_->wait_until(__abs_time);}
1138};
1139
Howard Hinnantc834c512011-11-29 18:15:50 +00001140template <class _Rp>
1141future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001142 : __state_(__state)
1143{
1144 if (__state_->__has_future_attached())
Marshall Clow7b3742d2015-09-03 15:11:32 +00001145 __throw_future_error<future_errc::future_already_retrieved>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001146 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001147 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001148}
1149
Howard Hinnantccdd2032010-08-30 18:46:21 +00001150struct __release_shared_count
1151{
1152 void operator()(__shared_count* p) {p->__release_shared();}
1153};
1154
Howard Hinnantc834c512011-11-29 18:15:50 +00001155template <class _Rp>
1156future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001157{
1158 if (__state_)
1159 __state_->__release_shared();
1160}
1161
Howard Hinnantc834c512011-11-29 18:15:50 +00001162template <class _Rp>
1163_Rp
1164future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001165{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001166 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001167 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001168 __state_ = nullptr;
1169 return __s->move();
1170}
1171
Howard Hinnantc834c512011-11-29 18:15:50 +00001172template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001173class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001174{
Howard Hinnantc834c512011-11-29 18:15:50 +00001175 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001176
Howard Hinnantc834c512011-11-29 18:15:50 +00001177 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001178
1179 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001180 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001181
Howard Hinnant74279a52010-09-04 23:28:19 +00001182#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001183 template <class _R1, class _Fp>
1184 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1185 template <class _R1, class _Fp>
1186 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001187#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001188 template <class _R1, class _Fp>
1189 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1190 template <class _R1, class _Fp>
1191 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001192#endif
1193
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001194public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001195 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001196 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001197#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001198 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001199 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001200 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1201 future(const future&) = delete;
1202 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001203 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001204 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001205 {
1206 future(std::move(__rhs)).swap(*this);
1207 return *this;
1208 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001209#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001210private:
1211 future(const future&);
1212 future& operator=(const future&);
1213public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001214#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001215 ~future();
Howard Hinnantc834c512011-11-29 18:15:50 +00001216 shared_future<_Rp&> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001217
1218 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001219 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001220
Howard Hinnant684902d2010-09-22 14:16:26 +00001221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001222 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001223
1224 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001226 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001227
Howard Hinnant684902d2010-09-22 14:16:26 +00001228 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001229 void wait() const {__state_->wait();}
1230 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001232 future_status
1233 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1234 {return __state_->wait_for(__rel_time);}
1235 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001237 future_status
1238 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1239 {return __state_->wait_until(__abs_time);}
1240};
1241
Howard Hinnantc834c512011-11-29 18:15:50 +00001242template <class _Rp>
1243future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001244 : __state_(__state)
1245{
1246 if (__state_->__has_future_attached())
Marshall Clow7b3742d2015-09-03 15:11:32 +00001247 __throw_future_error<future_errc::future_already_retrieved>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001248 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001249 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001250}
1251
Howard Hinnantc834c512011-11-29 18:15:50 +00001252template <class _Rp>
1253future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001254{
1255 if (__state_)
1256 __state_->__release_shared();
1257}
1258
Howard Hinnantc834c512011-11-29 18:15:50 +00001259template <class _Rp>
1260_Rp&
1261future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001262{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001263 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001264 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001265 __state_ = nullptr;
1266 return __s->copy();
1267}
1268
1269template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001270class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001271{
1272 __assoc_sub_state* __state_;
1273
1274 explicit future(__assoc_sub_state* __state);
1275
1276 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001277 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001278
Howard Hinnant74279a52010-09-04 23:28:19 +00001279#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001280 template <class _R1, class _Fp>
1281 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1282 template <class _R1, class _Fp>
1283 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001284#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001285 template <class _R1, class _Fp>
1286 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1287 template <class _R1, class _Fp>
1288 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001289#endif
1290
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001291public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001293 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001294#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001296 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001297 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1298 future(const future&) = delete;
1299 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001301 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001302 {
1303 future(std::move(__rhs)).swap(*this);
1304 return *this;
1305 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001306#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001307private:
1308 future(const future&);
1309 future& operator=(const future&);
1310public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001311#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001312 ~future();
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001313 shared_future<void> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001314
1315 // retrieving the value
1316 void get();
1317
Howard Hinnant684902d2010-09-22 14:16:26 +00001318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001319 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001320
1321 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001322 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001323 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001324
Howard Hinnant684902d2010-09-22 14:16:26 +00001325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001326 void wait() const {__state_->wait();}
1327 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001328 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001329 future_status
1330 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1331 {return __state_->wait_for(__rel_time);}
1332 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001334 future_status
1335 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1336 {return __state_->wait_until(__abs_time);}
1337};
1338
Howard Hinnantc834c512011-11-29 18:15:50 +00001339template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001340inline _LIBCPP_INLINE_VISIBILITY
1341void
Howard Hinnant22448042012-07-21 17:46:55 +00001342swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001343{
1344 __x.swap(__y);
1345}
1346
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001347// promise<R>
1348
Howard Hinnant944510a2011-06-14 19:58:17 +00001349template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001350
Howard Hinnantc834c512011-11-29 18:15:50 +00001351template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001352class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001353{
Howard Hinnantc834c512011-11-29 18:15:50 +00001354 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001355
Howard Hinnant684902d2010-09-22 14:16:26 +00001356 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001357 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001358
1359 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001360public:
1361 promise();
1362 template <class _Alloc>
1363 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001364#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001366 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001367 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1368 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001369#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001370private:
1371 promise(const promise& __rhs);
1372public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001373#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001374 ~promise();
1375
1376 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001377#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001378 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001379 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001380 {
1381 promise(std::move(__rhs)).swap(*this);
1382 return *this;
1383 }
1384 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001385#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001386private:
1387 promise& operator=(const promise& __rhs);
1388public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001389#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001390 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001391 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001392
1393 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001394 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001395
1396 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001397 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001398#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001399 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001400#endif
1401 void set_exception(exception_ptr __p);
1402
1403 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001404 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001405#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001406 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001407#endif
1408 void set_exception_at_thread_exit(exception_ptr __p);
1409};
1410
Howard Hinnantc834c512011-11-29 18:15:50 +00001411template <class _Rp>
1412promise<_Rp>::promise()
1413 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001414{
1415}
1416
Howard Hinnantc834c512011-11-29 18:15:50 +00001417template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001418template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001419promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001420{
Eric Fiselier0d109272014-10-23 06:24:45 +00001421 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1422 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001423 typedef __allocator_destructor<_A2> _D2;
1424 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001425 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1426 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1427 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001428}
1429
Howard Hinnantc834c512011-11-29 18:15:50 +00001430template <class _Rp>
1431promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001432{
1433 if (__state_)
1434 {
1435 if (!__state_->__has_value() && __state_->use_count() > 1)
1436 __state_->set_exception(make_exception_ptr(
1437 future_error(make_error_code(future_errc::broken_promise))
1438 ));
1439 __state_->__release_shared();
1440 }
1441}
1442
Howard Hinnantc834c512011-11-29 18:15:50 +00001443template <class _Rp>
1444future<_Rp>
1445promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001446{
1447 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001448 __throw_future_error<future_errc::no_state>();
Howard Hinnantc834c512011-11-29 18:15:50 +00001449 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001450}
1451
Howard Hinnantc834c512011-11-29 18:15:50 +00001452template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001453void
Howard Hinnantc834c512011-11-29 18:15:50 +00001454promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001455{
1456 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001457 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001458 __state_->set_value(__r);
1459}
1460
Howard Hinnant74279a52010-09-04 23:28:19 +00001461#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001462
Howard Hinnantc834c512011-11-29 18:15:50 +00001463template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001464void
Howard Hinnantc834c512011-11-29 18:15:50 +00001465promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001466{
1467 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001468 __throw_future_error<future_errc::no_state>();
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001469 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001470}
1471
Howard Hinnant74279a52010-09-04 23:28:19 +00001472#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001473
Howard Hinnantc834c512011-11-29 18:15:50 +00001474template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001475void
Howard Hinnantc834c512011-11-29 18:15:50 +00001476promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001477{
1478 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001479 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001480 __state_->set_exception(__p);
1481}
1482
Howard Hinnantc834c512011-11-29 18:15:50 +00001483template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001484void
Howard Hinnantc834c512011-11-29 18:15:50 +00001485promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001486{
1487 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001488 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001489 __state_->set_value_at_thread_exit(__r);
1490}
1491
Howard Hinnant74279a52010-09-04 23:28:19 +00001492#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001493
Howard Hinnantc834c512011-11-29 18:15:50 +00001494template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001495void
Howard Hinnantc834c512011-11-29 18:15:50 +00001496promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001497{
1498 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001499 __throw_future_error<future_errc::no_state>();
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001500 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001501}
1502
Howard Hinnant74279a52010-09-04 23:28:19 +00001503#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504
Howard Hinnantc834c512011-11-29 18:15:50 +00001505template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001506void
Howard Hinnantc834c512011-11-29 18:15:50 +00001507promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001508{
1509 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001510 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001511 __state_->set_exception_at_thread_exit(__p);
1512}
1513
1514// promise<R&>
1515
Howard Hinnantc834c512011-11-29 18:15:50 +00001516template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001517class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001518{
Howard Hinnantc834c512011-11-29 18:15:50 +00001519 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001520
Howard Hinnant684902d2010-09-22 14:16:26 +00001521 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001522 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001523
1524 template <class> friend class packaged_task;
1525
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001526public:
1527 promise();
1528 template <class _Allocator>
1529 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001530#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001531 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001532 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001533 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1534 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001535#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001536private:
1537 promise(const promise& __rhs);
1538public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001539#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001540 ~promise();
1541
1542 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001543#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001544 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001545 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001546 {
1547 promise(std::move(__rhs)).swap(*this);
1548 return *this;
1549 }
1550 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001551#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001552private:
1553 promise& operator=(const promise& __rhs);
1554public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001555#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001557 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001558
1559 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001560 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001561
1562 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001563 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001564 void set_exception(exception_ptr __p);
1565
1566 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001567 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001568 void set_exception_at_thread_exit(exception_ptr __p);
1569};
1570
Howard Hinnantc834c512011-11-29 18:15:50 +00001571template <class _Rp>
1572promise<_Rp&>::promise()
1573 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001574{
1575}
1576
Howard Hinnantc834c512011-11-29 18:15:50 +00001577template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001578template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001579promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001580{
Eric Fiselier0d109272014-10-23 06:24:45 +00001581 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1582 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001583 typedef __allocator_destructor<_A2> _D2;
1584 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001585 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1586 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1587 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001588}
1589
Howard Hinnantc834c512011-11-29 18:15:50 +00001590template <class _Rp>
1591promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001592{
1593 if (__state_)
1594 {
1595 if (!__state_->__has_value() && __state_->use_count() > 1)
1596 __state_->set_exception(make_exception_ptr(
1597 future_error(make_error_code(future_errc::broken_promise))
1598 ));
1599 __state_->__release_shared();
1600 }
1601}
1602
Howard Hinnantc834c512011-11-29 18:15:50 +00001603template <class _Rp>
1604future<_Rp&>
1605promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001606{
1607 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001608 __throw_future_error<future_errc::no_state>();
Howard Hinnantc834c512011-11-29 18:15:50 +00001609 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001610}
1611
Howard Hinnantc834c512011-11-29 18:15:50 +00001612template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001613void
Howard Hinnantc834c512011-11-29 18:15:50 +00001614promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001615{
1616 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001617 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001618 __state_->set_value(__r);
1619}
1620
Howard Hinnantc834c512011-11-29 18:15:50 +00001621template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001622void
Howard Hinnantc834c512011-11-29 18:15:50 +00001623promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001624{
1625 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001626 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001627 __state_->set_exception(__p);
1628}
1629
Howard Hinnantc834c512011-11-29 18:15:50 +00001630template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001631void
Howard Hinnantc834c512011-11-29 18:15:50 +00001632promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001633{
1634 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001635 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001636 __state_->set_value_at_thread_exit(__r);
1637}
1638
Howard Hinnantc834c512011-11-29 18:15:50 +00001639template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001640void
Howard Hinnantc834c512011-11-29 18:15:50 +00001641promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001642{
1643 if (__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00001644 __throw_future_error<future_errc::no_state>();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001645 __state_->set_exception_at_thread_exit(__p);
1646}
1647
1648// promise<void>
1649
1650template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001651class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001652{
1653 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001654
Howard Hinnant684902d2010-09-22 14:16:26 +00001655 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001656 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001657
1658 template <class> friend class packaged_task;
1659
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001660public:
1661 promise();
1662 template <class _Allocator>
1663 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001664#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001665 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001666 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001667 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1668 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001669#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001670private:
1671 promise(const promise& __rhs);
1672public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001673#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001674 ~promise();
1675
1676 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001677#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001678 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001679 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001680 {
1681 promise(std::move(__rhs)).swap(*this);
1682 return *this;
1683 }
1684 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001685#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001686private:
1687 promise& operator=(const promise& __rhs);
1688public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001689#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001690 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001691 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001692
1693 // retrieving the result
1694 future<void> get_future();
1695
1696 // setting the result
1697 void set_value();
1698 void set_exception(exception_ptr __p);
1699
1700 // setting the result with deferred notification
1701 void set_value_at_thread_exit();
1702 void set_exception_at_thread_exit(exception_ptr __p);
1703};
1704
1705template <class _Alloc>
1706promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1707{
Eric Fiselier0d109272014-10-23 06:24:45 +00001708 typedef __assoc_sub_state_alloc<_Alloc> _State;
1709 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001710 typedef __allocator_destructor<_A2> _D2;
1711 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001712 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1713 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1714 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001715}
1716
Howard Hinnantc834c512011-11-29 18:15:50 +00001717template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001718inline _LIBCPP_INLINE_VISIBILITY
1719void
Howard Hinnant22448042012-07-21 17:46:55 +00001720swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001721{
1722 __x.swap(__y);
1723}
1724
Howard Hinnantc834c512011-11-29 18:15:50 +00001725template <class _Rp, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001726 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001727 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001728
Howard Hinnantccdd2032010-08-30 18:46:21 +00001729#ifndef _LIBCPP_HAS_NO_VARIADICS
1730
1731// packaged_task
1732
1733template<class _Fp> class __packaged_task_base;
1734
Howard Hinnantc834c512011-11-29 18:15:50 +00001735template<class _Rp, class ..._ArgTypes>
1736class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001737{
1738 __packaged_task_base(const __packaged_task_base&);
1739 __packaged_task_base& operator=(const __packaged_task_base&);
1740public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001741 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001742 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001743 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001744 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001745 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001746 virtual void destroy() = 0;
1747 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001748 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001749};
1750
1751template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1752
Howard Hinnantc834c512011-11-29 18:15:50 +00001753template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1754class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1755 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001756{
Howard Hinnantc834c512011-11-29 18:15:50 +00001757 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001758public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001759 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001760 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001761 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001762 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001763 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001764 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001765 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001766 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001767 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001768 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001769 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001770 virtual void destroy();
1771 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001772 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001773};
1774
Howard Hinnantc834c512011-11-29 18:15:50 +00001775template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001776void
Howard Hinnantc834c512011-11-29 18:15:50 +00001777__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001778 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001779{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001780 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001781}
1782
Howard Hinnantc834c512011-11-29 18:15:50 +00001783template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001784void
Howard Hinnantc834c512011-11-29 18:15:50 +00001785__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001786{
Howard Hinnantc834c512011-11-29 18:15:50 +00001787 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001788}
1789
Howard Hinnantc834c512011-11-29 18:15:50 +00001790template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001791void
Howard Hinnantc834c512011-11-29 18:15:50 +00001792__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001793{
Eric Fiselier0d109272014-10-23 06:24:45 +00001794 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1795 typedef allocator_traits<_Ap> _ATraits;
1796 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001797 _Ap __a(__f_.second());
1798 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001799 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001800}
1801
Howard Hinnantc834c512011-11-29 18:15:50 +00001802template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1803_Rp
1804__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001805{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001806 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001807}
1808
Howard Hinnant944510a2011-06-14 19:58:17 +00001809template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001810
Howard Hinnantc834c512011-11-29 18:15:50 +00001811template<class _Rp, class ..._ArgTypes>
1812class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001813{
Howard Hinnantc834c512011-11-29 18:15:50 +00001814 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001815 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001816 __base* __f_;
1817
1818public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001819 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001820
1821 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001822 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001823 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001824 template<class _Fp>
1825 __packaged_task_function(_Fp&& __f);
1826 template<class _Fp, class _Alloc>
1827 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001828
Howard Hinnant22448042012-07-21 17:46:55 +00001829 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1830 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001831
1832 __packaged_task_function(const __packaged_task_function&) = delete;
1833 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1834
1835 ~__packaged_task_function();
1836
Howard Hinnant22448042012-07-21 17:46:55 +00001837 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001838
Howard Hinnantc834c512011-11-29 18:15:50 +00001839 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001840};
1841
Howard Hinnantc834c512011-11-29 18:15:50 +00001842template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001843__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001844{
1845 if (__f.__f_ == nullptr)
1846 __f_ = nullptr;
1847 else if (__f.__f_ == (__base*)&__f.__buf_)
1848 {
1849 __f_ = (__base*)&__buf_;
1850 __f.__f_->__move_to(__f_);
1851 }
1852 else
1853 {
1854 __f_ = __f.__f_;
1855 __f.__f_ = nullptr;
1856 }
1857}
1858
Howard Hinnantc834c512011-11-29 18:15:50 +00001859template<class _Rp, class ..._ArgTypes>
1860template <class _Fp>
1861__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001862 : __f_(nullptr)
1863{
Marshall Clow733d60e2014-04-07 13:32:26 +00001864 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001865 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001866 if (sizeof(_FF) <= sizeof(__buf_))
1867 {
1868 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001869 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001870 }
1871 else
1872 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001873 typedef allocator<_FF> _Ap;
1874 _Ap __a;
1875 typedef __allocator_destructor<_Ap> _Dp;
1876 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1877 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001878 __f_ = __hold.release();
1879 }
1880}
1881
Howard Hinnantc834c512011-11-29 18:15:50 +00001882template<class _Rp, class ..._ArgTypes>
1883template <class _Fp, class _Alloc>
1884__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1885 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001886 : __f_(nullptr)
1887{
Marshall Clow733d60e2014-04-07 13:32:26 +00001888 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001889 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001890 if (sizeof(_FF) <= sizeof(__buf_))
1891 {
1892 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001893 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001894 }
1895 else
1896 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001897 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001898 _Ap __a(__a0);
1899 typedef __allocator_destructor<_Ap> _Dp;
1900 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001901 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1902 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1903 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001904 }
1905}
1906
Howard Hinnantc834c512011-11-29 18:15:50 +00001907template<class _Rp, class ..._ArgTypes>
1908__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001909__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001910{
1911 if (__f_ == (__base*)&__buf_)
1912 __f_->destroy();
1913 else if (__f_)
1914 __f_->destroy_deallocate();
1915 __f_ = nullptr;
1916 if (__f.__f_ == nullptr)
1917 __f_ = nullptr;
1918 else if (__f.__f_ == (__base*)&__f.__buf_)
1919 {
1920 __f_ = (__base*)&__buf_;
1921 __f.__f_->__move_to(__f_);
1922 }
1923 else
1924 {
1925 __f_ = __f.__f_;
1926 __f.__f_ = nullptr;
1927 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001928 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001929}
1930
Howard Hinnantc834c512011-11-29 18:15:50 +00001931template<class _Rp, class ..._ArgTypes>
1932__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001933{
1934 if (__f_ == (__base*)&__buf_)
1935 __f_->destroy();
1936 else if (__f_)
1937 __f_->destroy_deallocate();
1938}
1939
Howard Hinnantc834c512011-11-29 18:15:50 +00001940template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001941void
Howard Hinnant22448042012-07-21 17:46:55 +00001942__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001943{
1944 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1945 {
1946 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1947 __base* __t = (__base*)&__tempbuf;
1948 __f_->__move_to(__t);
1949 __f_->destroy();
1950 __f_ = nullptr;
1951 __f.__f_->__move_to((__base*)&__buf_);
1952 __f.__f_->destroy();
1953 __f.__f_ = nullptr;
1954 __f_ = (__base*)&__buf_;
1955 __t->__move_to((__base*)&__f.__buf_);
1956 __t->destroy();
1957 __f.__f_ = (__base*)&__f.__buf_;
1958 }
1959 else if (__f_ == (__base*)&__buf_)
1960 {
1961 __f_->__move_to((__base*)&__f.__buf_);
1962 __f_->destroy();
1963 __f_ = __f.__f_;
1964 __f.__f_ = (__base*)&__f.__buf_;
1965 }
1966 else if (__f.__f_ == (__base*)&__f.__buf_)
1967 {
1968 __f.__f_->__move_to((__base*)&__buf_);
1969 __f.__f_->destroy();
1970 __f.__f_ = __f_;
1971 __f_ = (__base*)&__buf_;
1972 }
1973 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001974 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001975}
1976
Howard Hinnantc834c512011-11-29 18:15:50 +00001977template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001978inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001979_Rp
1980__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001981{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001982 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001983}
1984
Howard Hinnantc834c512011-11-29 18:15:50 +00001985template<class _Rp, class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001986class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001987{
1988public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001989 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001990
1991private:
1992 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1993 promise<result_type> __p_;
1994
1995public:
1996 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00001997 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001998 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00001999 template <class _Fp,
2000 class = typename enable_if
2001 <
2002 !is_same<
2003 typename decay<_Fp>::type,
2004 packaged_task
2005 >::value
2006 >::type
2007 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002008 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002009 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002010 template <class _Fp, class _Allocator,
2011 class = typename enable_if
2012 <
2013 !is_same<
2014 typename decay<_Fp>::type,
2015 packaged_task
2016 >::value
2017 >::type
2018 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002019 _LIBCPP_INLINE_VISIBILITY
Marshall Clowc317e022015-06-30 14:16:49 +00002020 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002021 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002022 __p_(allocator_arg, __a) {}
2023 // ~packaged_task() = default;
2024
2025 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002026 packaged_task(const packaged_task&) = delete;
2027 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002028
2029 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002030 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002031 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002032 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002033 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002034 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002035 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002036 __f_ = _VSTD::move(__other.__f_);
2037 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002038 return *this;
2039 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002040 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002041 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002042 {
2043 __f_.swap(__other.__f_);
2044 __p_.swap(__other.__p_);
2045 }
2046
Howard Hinnant684902d2010-09-22 14:16:26 +00002047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002048 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002049
2050 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002052 future<result_type> get_future() {return __p_.get_future();}
2053
2054 // execution
2055 void operator()(_ArgTypes... __args);
2056 void make_ready_at_thread_exit(_ArgTypes... __args);
2057
2058 void reset();
2059};
2060
Howard Hinnantc834c512011-11-29 18:15:50 +00002061template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002062void
Howard Hinnantc834c512011-11-29 18:15:50 +00002063packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002064{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002065 if (__p_.__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00002066 __throw_future_error<future_errc::no_state>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00002067 if (__p_.__state_->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +00002068 __throw_future_error<future_errc::promise_already_satisfied>();
2069#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002070 try
2071 {
2072#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002073 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002074#ifndef _LIBCPP_NO_EXCEPTIONS
2075 }
2076 catch (...)
2077 {
2078 __p_.set_exception(current_exception());
2079 }
2080#endif // _LIBCPP_NO_EXCEPTIONS
2081}
2082
Howard Hinnantc834c512011-11-29 18:15:50 +00002083template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002084void
Howard Hinnantc834c512011-11-29 18:15:50 +00002085packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002086{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002087 if (__p_.__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00002088 __throw_future_error<future_errc::no_state>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00002089 if (__p_.__state_->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +00002090 __throw_future_error<future_errc::promise_already_satisfied>();
2091#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002092 try
2093 {
2094#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002095 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002096#ifndef _LIBCPP_NO_EXCEPTIONS
2097 }
2098 catch (...)
2099 {
2100 __p_.set_exception_at_thread_exit(current_exception());
2101 }
2102#endif // _LIBCPP_NO_EXCEPTIONS
2103}
2104
Howard Hinnantc834c512011-11-29 18:15:50 +00002105template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002106void
Howard Hinnantc834c512011-11-29 18:15:50 +00002107packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002108{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002109 if (!valid())
Marshall Clow7b3742d2015-09-03 15:11:32 +00002110 __throw_future_error<future_errc::no_state>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00002111 __p_ = promise<result_type>();
2112}
2113
2114template<class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002115class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002116{
2117public:
2118 typedef void result_type;
2119
2120private:
2121 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2122 promise<result_type> __p_;
2123
2124public:
2125 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002126 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002127 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002128 template <class _Fp,
2129 class = typename enable_if
2130 <
2131 !is_same<
2132 typename decay<_Fp>::type,
2133 packaged_task
2134 >::value
2135 >::type
2136 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002137 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002138 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002139 template <class _Fp, class _Allocator,
2140 class = typename enable_if
2141 <
2142 !is_same<
2143 typename decay<_Fp>::type,
2144 packaged_task
2145 >::value
2146 >::type
2147 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002148 _LIBCPP_INLINE_VISIBILITY
Marshall Clow976e4822015-06-30 18:28:35 +00002149 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
Howard Hinnantc834c512011-11-29 18:15:50 +00002150 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002151 __p_(allocator_arg, __a) {}
2152 // ~packaged_task() = default;
2153
2154 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002155 packaged_task(const packaged_task&) = delete;
2156 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002157
2158 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002159 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002160 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002161 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002162 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002163 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002164 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002165 __f_ = _VSTD::move(__other.__f_);
2166 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002167 return *this;
2168 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002169 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002170 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002171 {
2172 __f_.swap(__other.__f_);
2173 __p_.swap(__other.__p_);
2174 }
2175
Howard Hinnant684902d2010-09-22 14:16:26 +00002176 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002177 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002178
2179 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002180 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002181 future<result_type> get_future() {return __p_.get_future();}
2182
2183 // execution
2184 void operator()(_ArgTypes... __args);
2185 void make_ready_at_thread_exit(_ArgTypes... __args);
2186
2187 void reset();
2188};
2189
2190template<class ..._ArgTypes>
2191void
2192packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2193{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002194 if (__p_.__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00002195 __throw_future_error<future_errc::no_state>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00002196 if (__p_.__state_->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +00002197 __throw_future_error<future_errc::promise_already_satisfied>();
2198#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002199 try
2200 {
2201#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002202 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002203 __p_.set_value();
2204#ifndef _LIBCPP_NO_EXCEPTIONS
2205 }
2206 catch (...)
2207 {
2208 __p_.set_exception(current_exception());
2209 }
2210#endif // _LIBCPP_NO_EXCEPTIONS
2211}
2212
2213template<class ..._ArgTypes>
2214void
2215packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2216{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002217 if (__p_.__state_ == nullptr)
Marshall Clow7b3742d2015-09-03 15:11:32 +00002218 __throw_future_error<future_errc::no_state>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00002219 if (__p_.__state_->__has_value())
Marshall Clow7b3742d2015-09-03 15:11:32 +00002220 __throw_future_error<future_errc::promise_already_satisfied>();
2221#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002222 try
2223 {
2224#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002225 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002226 __p_.set_value_at_thread_exit();
2227#ifndef _LIBCPP_NO_EXCEPTIONS
2228 }
2229 catch (...)
2230 {
2231 __p_.set_exception_at_thread_exit(current_exception());
2232 }
2233#endif // _LIBCPP_NO_EXCEPTIONS
2234}
2235
2236template<class ..._ArgTypes>
2237void
2238packaged_task<void(_ArgTypes...)>::reset()
2239{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002240 if (!valid())
Marshall Clow7b3742d2015-09-03 15:11:32 +00002241 __throw_future_error<future_errc::no_state>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00002242 __p_ = promise<result_type>();
2243}
2244
2245template <class _Callable>
2246inline _LIBCPP_INLINE_VISIBILITY
2247void
Howard Hinnant22448042012-07-21 17:46:55 +00002248swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002249{
2250 __x.swap(__y);
2251}
2252
2253template <class _Callable, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002254struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00002255 : public true_type {};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002256
Howard Hinnantc834c512011-11-29 18:15:50 +00002257template <class _Rp, class _Fp>
2258future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002259#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002260__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002261#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002262__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002263#endif
2264{
Howard Hinnantc834c512011-11-29 18:15:50 +00002265 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2266 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2267 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002268}
2269
Howard Hinnantc834c512011-11-29 18:15:50 +00002270template <class _Rp, class _Fp>
2271future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002272#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002273__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002274#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002275__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002276#endif
2277{
Howard Hinnantc834c512011-11-29 18:15:50 +00002278 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2279 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2280 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2281 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002282}
2283
Howard Hinnantc834c512011-11-29 18:15:50 +00002284template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002285class __async_func
2286{
Howard Hinnantc834c512011-11-29 18:15:50 +00002287 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002288
2289public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002290 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002291
2292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002293 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002294 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002295
2296 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002297 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002298
Howard Hinnantc834c512011-11-29 18:15:50 +00002299 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002300 {
2301 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2302 return __execute(_Index());
2303 }
2304private:
2305 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002306 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002307 __execute(__tuple_indices<_Indices...>)
2308 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002309 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002310 }
2311};
2312
Marshall Clowd56a5b62013-11-03 22:06:53 +00002313inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002314{ return (int(__policy) & int(__value)) != 0; }
2315
Howard Hinnantc834c512011-11-29 18:15:50 +00002316template <class _Fp, class... _Args>
2317future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2318async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002319{
Howard Hinnantc834c512011-11-29 18:15:50 +00002320 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2321 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002322
2323#ifndef _LIBCPP_NO_EXCEPTIONS
2324 try
2325 {
2326#endif
2327 if (__does_policy_contain(__policy, launch::async))
2328 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002329 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002330#ifndef _LIBCPP_NO_EXCEPTIONS
2331 }
2332 catch ( ... ) { if (__policy == launch::async) throw ; }
2333#endif
2334
2335 if (__does_policy_contain(__policy, launch::deferred))
2336 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002337 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002338 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002339}
2340
Howard Hinnantc834c512011-11-29 18:15:50 +00002341template <class _Fp, class... _Args>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002342inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002343future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2344async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002345{
Howard Hinnantc834c512011-11-29 18:15:50 +00002346 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002347 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002348}
2349
2350#endif // _LIBCPP_HAS_NO_VARIADICS
2351
Howard Hinnante6a10852010-09-03 21:46:37 +00002352// shared_future
2353
Howard Hinnantc834c512011-11-29 18:15:50 +00002354template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002355class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002356{
Howard Hinnantc834c512011-11-29 18:15:50 +00002357 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002358
2359public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002360 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002361 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002362 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002363 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2364 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002365#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002367 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002368 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002369 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002370 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002371 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002372#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002373 ~shared_future();
2374 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002375#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002376 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002377 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002378 {
2379 shared_future(std::move(__rhs)).swap(*this);
2380 return *this;
2381 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002382#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002383
2384 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002386 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002387
Howard Hinnant684902d2010-09-22 14:16:26 +00002388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002389 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002390
2391 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002392 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002393 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002394
Howard Hinnant684902d2010-09-22 14:16:26 +00002395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002396 void wait() const {__state_->wait();}
2397 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002398 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002399 future_status
2400 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2401 {return __state_->wait_for(__rel_time);}
2402 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002403 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002404 future_status
2405 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2406 {return __state_->wait_until(__abs_time);}
2407};
2408
Howard Hinnantc834c512011-11-29 18:15:50 +00002409template <class _Rp>
2410shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002411{
2412 if (__state_)
2413 __state_->__release_shared();
2414}
2415
Howard Hinnantc834c512011-11-29 18:15:50 +00002416template <class _Rp>
2417shared_future<_Rp>&
2418shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002419{
2420 if (__rhs.__state_)
2421 __rhs.__state_->__add_shared();
2422 if (__state_)
2423 __state_->__release_shared();
2424 __state_ = __rhs.__state_;
2425 return *this;
2426}
2427
Howard Hinnantc834c512011-11-29 18:15:50 +00002428template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002429class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002430{
Howard Hinnantc834c512011-11-29 18:15:50 +00002431 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002432
2433public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002434 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002435 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002436 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002437 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2438 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002439#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002441 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002442 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002444 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002445 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002446#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002447 ~shared_future();
2448 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002449#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002451 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002452 {
2453 shared_future(std::move(__rhs)).swap(*this);
2454 return *this;
2455 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002456#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002457
2458 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002459 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002460 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002461
Howard Hinnant684902d2010-09-22 14:16:26 +00002462 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002463 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002464
2465 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002467 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002468
Howard Hinnant684902d2010-09-22 14:16:26 +00002469 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002470 void wait() const {__state_->wait();}
2471 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002473 future_status
2474 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2475 {return __state_->wait_for(__rel_time);}
2476 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002478 future_status
2479 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2480 {return __state_->wait_until(__abs_time);}
2481};
2482
Howard Hinnantc834c512011-11-29 18:15:50 +00002483template <class _Rp>
2484shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002485{
2486 if (__state_)
2487 __state_->__release_shared();
2488}
2489
Howard Hinnantc834c512011-11-29 18:15:50 +00002490template <class _Rp>
2491shared_future<_Rp&>&
2492shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002493{
2494 if (__rhs.__state_)
2495 __rhs.__state_->__add_shared();
2496 if (__state_)
2497 __state_->__release_shared();
2498 __state_ = __rhs.__state_;
2499 return *this;
2500}
2501
2502template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00002503class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002504{
2505 __assoc_sub_state* __state_;
2506
2507public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002508 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002509 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002511 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2512 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002513#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002514 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002515 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002516 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002517 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002518 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002519 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002520#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002521 ~shared_future();
2522 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002523#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002525 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002526 {
2527 shared_future(std::move(__rhs)).swap(*this);
2528 return *this;
2529 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002530#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002531
2532 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002534 void get() const {__state_->copy();}
2535
Howard Hinnant684902d2010-09-22 14:16:26 +00002536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002537 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002538
2539 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002541 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002542
Howard Hinnant684902d2010-09-22 14:16:26 +00002543 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002544 void wait() const {__state_->wait();}
2545 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002547 future_status
2548 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2549 {return __state_->wait_for(__rel_time);}
2550 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002552 future_status
2553 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2554 {return __state_->wait_until(__abs_time);}
2555};
2556
Howard Hinnantc834c512011-11-29 18:15:50 +00002557template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002558inline _LIBCPP_INLINE_VISIBILITY
2559void
Howard Hinnant22448042012-07-21 17:46:55 +00002560swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002561{
2562 __x.swap(__y);
2563}
2564
Howard Hinnantc834c512011-11-29 18:15:50 +00002565template <class _Rp>
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002566inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002567shared_future<_Rp>
2568future<_Rp>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002569{
Howard Hinnantc834c512011-11-29 18:15:50 +00002570 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002571}
2572
Howard Hinnantc834c512011-11-29 18:15:50 +00002573template <class _Rp>
Howard Hinnante6a10852010-09-03 21:46:37 +00002574inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002575shared_future<_Rp&>
2576future<_Rp&>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002577{
Howard Hinnantc834c512011-11-29 18:15:50 +00002578 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002579}
2580
Howard Hinnante65e8e32010-12-02 16:45:21 +00002581#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2582
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002583inline _LIBCPP_INLINE_VISIBILITY
2584shared_future<void>
2585future<void>::share()
2586{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002587 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002588}
2589
Howard Hinnante65e8e32010-12-02 16:45:21 +00002590#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2591
Howard Hinnantc51e1022010-05-11 19:42:16 +00002592_LIBCPP_END_NAMESPACE_STD
2593
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002594#endif // !_LIBCPP_HAS_NO_THREADS
2595
Howard Hinnantc51e1022010-05-11 19:42:16 +00002596#endif // _LIBCPP_FUTURE