blob: 7cd88cb726bae3e60fe857f1912800593f49a24a [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>
332 explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333 ~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 Roelofs39cb6bf2014-09-05 19:45:05 +0000377#ifndef _LIBCPP_HAS_NO_THREADS
378#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
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000515class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000516 : public __shared_count
517{
518protected:
519 exception_ptr __exception_;
520 mutable mutex __mut_;
521 mutable condition_variable __cv_;
522 unsigned __state_;
523
Howard Hinnant719bda32011-05-28 14:41:13 +0000524 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000525 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000526public:
527 enum
528 {
529 __constructed = 1,
530 __future_attached = 2,
531 ready = 4,
532 deferred = 8
533 };
534
Howard Hinnant684902d2010-09-22 14:16:26 +0000535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000536 __assoc_sub_state() : __state_(0) {}
537
Howard Hinnant684902d2010-09-22 14:16:26 +0000538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000539 bool __has_value() const
540 {return (__state_ & __constructed) || (__exception_ != nullptr);}
541
Howard Hinnant684902d2010-09-22 14:16:26 +0000542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante667ecc2013-01-14 20:01:24 +0000543 void __set_future_attached()
544 {
545 lock_guard<mutex> __lk(__mut_);
546 __state_ |= __future_attached;
547 }
Howard Hinnant684902d2010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000549 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000550
Howard Hinnant684902d2010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000552 void __set_deferred() {__state_ |= deferred;}
553
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000554 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000555 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000556 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000557
558 void set_value();
559 void set_value_at_thread_exit();
560
561 void set_exception(exception_ptr __p);
562 void set_exception_at_thread_exit(exception_ptr __p);
563
564 void copy();
565
Howard Hinnantccdd2032010-08-30 18:46:21 +0000566 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567 template <class _Rep, class _Period>
568 future_status
569 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
570 template <class _Clock, class _Duration>
571 future_status
572 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000573
574 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000575};
576
Howard Hinnantf4712b92010-08-28 21:01:06 +0000577template <class _Clock, class _Duration>
578future_status
579__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
580{
581 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000582 if (__state_ & deferred)
583 return future_status::deferred;
584 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000585 __cv_.wait_until(__lk, __abs_time);
586 if (__state_ & ready)
587 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000588 return future_status::timeout;
589}
590
591template <class _Rep, class _Period>
592inline _LIBCPP_INLINE_VISIBILITY
593future_status
594__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
595{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000596 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000597}
598
Howard Hinnantc834c512011-11-29 18:15:50 +0000599template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000600class __assoc_state
601 : public __assoc_sub_state
602{
603 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000604 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000605protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000606 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000607
Howard Hinnant719bda32011-05-28 14:41:13 +0000608 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000609public:
610
611 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000612#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000613 void set_value(_Arg&& __arg);
614#else
615 void set_value(_Arg& __arg);
616#endif
617
618 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000619#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620 void set_value_at_thread_exit(_Arg&& __arg);
621#else
622 void set_value_at_thread_exit(_Arg& __arg);
623#endif
624
Howard Hinnantc834c512011-11-29 18:15:50 +0000625 _Rp move();
626 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000627};
628
Howard Hinnantc834c512011-11-29 18:15:50 +0000629template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000630void
Howard Hinnantc834c512011-11-29 18:15:50 +0000631__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000632{
633 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000634 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000635 delete this;
636}
637
Howard Hinnantc834c512011-11-29 18:15:50 +0000638template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000639template <class _Arg>
640void
Howard Hinnant74279a52010-09-04 23:28:19 +0000641#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000642__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000643#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000644__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000645#endif
646{
647 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000648#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000649 if (this->__has_value())
650 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000651#endif
Howard Hinnantc834c512011-11-29 18:15:50 +0000652 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000653 this->__state_ |= base::__constructed | base::ready;
654 __lk.unlock();
655 __cv_.notify_all();
656}
657
Howard Hinnantc834c512011-11-29 18:15:50 +0000658template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000659template <class _Arg>
660void
Howard Hinnant74279a52010-09-04 23:28:19 +0000661#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000662__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000663#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000664__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000665#endif
666{
667 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000668#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000669 if (this->__has_value())
670 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000671#endif
Howard Hinnantc834c512011-11-29 18:15:50 +0000672 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000673 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000674 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675 __lk.unlock();
676}
677
Howard Hinnantc834c512011-11-29 18:15:50 +0000678template <class _Rp>
679_Rp
680__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000681{
682 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000683 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000684 if (this->__exception_ != nullptr)
685 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000686 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000687}
688
Howard Hinnantc834c512011-11-29 18:15:50 +0000689template <class _Rp>
690typename add_lvalue_reference<_Rp>::type
691__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000692{
693 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000694 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000695 if (this->__exception_ != nullptr)
696 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000697 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000698}
699
Howard Hinnantc834c512011-11-29 18:15:50 +0000700template <class _Rp>
701class __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000702 : public __assoc_sub_state
703{
704 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000705 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000706protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000707 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000708
Howard Hinnant719bda32011-05-28 14:41:13 +0000709 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000710public:
711
Howard Hinnantc834c512011-11-29 18:15:50 +0000712 void set_value(_Rp& __arg);
713 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000714
Howard Hinnantc834c512011-11-29 18:15:50 +0000715 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000716};
717
Howard Hinnantc834c512011-11-29 18:15:50 +0000718template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000719void
Howard Hinnantc834c512011-11-29 18:15:50 +0000720__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000721{
722 delete this;
723}
724
Howard Hinnantc834c512011-11-29 18:15:50 +0000725template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000726void
Howard Hinnantc834c512011-11-29 18:15:50 +0000727__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728{
729 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000730#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf4712b92010-08-28 21:01:06 +0000731 if (this->__has_value())
732 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000733#endif
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000734 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000735 this->__state_ |= base::__constructed | base::ready;
736 __lk.unlock();
737 __cv_.notify_all();
738}
739
Howard Hinnantc834c512011-11-29 18:15:50 +0000740template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000741void
Howard Hinnantc834c512011-11-29 18:15:50 +0000742__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743{
744 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000745#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf4712b92010-08-28 21:01:06 +0000746 if (this->__has_value())
747 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000748#endif
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 __lk.unlock();
753}
754
Howard Hinnantc834c512011-11-29 18:15:50 +0000755template <class _Rp>
756_Rp&
757__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000758{
759 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000760 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000761 if (this->__exception_ != nullptr)
762 rethrow_exception(this->__exception_);
763 return *__value_;
764}
765
Howard Hinnantc834c512011-11-29 18:15:50 +0000766template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000767class __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000768 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000769{
Howard Hinnantc834c512011-11-29 18:15:50 +0000770 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000771 _Alloc __alloc_;
772
Howard Hinnant719bda32011-05-28 14:41:13 +0000773 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000774public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000776 explicit __assoc_state_alloc(const _Alloc& __a)
777 : __alloc_(__a) {}
778};
779
Howard Hinnantc834c512011-11-29 18:15:50 +0000780template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000781void
Howard Hinnantc834c512011-11-29 18:15:50 +0000782__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000783{
784 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000785 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000786 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
787 this->~__assoc_state_alloc();
788 __a.deallocate(this, 1);
789}
790
Howard Hinnantc834c512011-11-29 18:15:50 +0000791template <class _Rp, class _Alloc>
792class __assoc_state_alloc<_Rp&, _Alloc>
793 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000794{
Howard Hinnantc834c512011-11-29 18:15:50 +0000795 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000796 _Alloc __alloc_;
797
Howard Hinnant719bda32011-05-28 14:41:13 +0000798 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000799public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000800 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000801 explicit __assoc_state_alloc(const _Alloc& __a)
802 : __alloc_(__a) {}
803};
804
Howard Hinnantc834c512011-11-29 18:15:50 +0000805template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000806void
Howard Hinnantc834c512011-11-29 18:15:50 +0000807__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000808{
809 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
810 this->~__assoc_state_alloc();
811 __a.deallocate(this, 1);
812}
813
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000814template <class _Alloc>
815class __assoc_sub_state_alloc
816 : public __assoc_sub_state
817{
818 typedef __assoc_sub_state base;
819 _Alloc __alloc_;
820
Howard Hinnant719bda32011-05-28 14:41:13 +0000821 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000822public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000823 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000824 explicit __assoc_sub_state_alloc(const _Alloc& __a)
825 : __alloc_(__a) {}
826};
827
828template <class _Alloc>
829void
Howard Hinnant719bda32011-05-28 14:41:13 +0000830__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000831{
Howard Hinnantf4712b92010-08-28 21:01:06 +0000832 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000833 this->~__assoc_sub_state_alloc();
834 __a.deallocate(this, 1);
835}
836
Howard Hinnantc834c512011-11-29 18:15:50 +0000837template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000838class __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000839 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000840{
Howard Hinnantc834c512011-11-29 18:15:50 +0000841 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000842
Howard Hinnantc834c512011-11-29 18:15:50 +0000843 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000844
845public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000846#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000847 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000848#endif
849
850 virtual void __execute();
851};
852
Howard Hinnant74279a52010-09-04 23:28:19 +0000853#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000854
Howard Hinnantc834c512011-11-29 18:15:50 +0000855template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000856inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000857__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
858 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000859{
860 this->__set_deferred();
861}
862
Howard Hinnant74279a52010-09-04 23:28:19 +0000863#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000864
Howard Hinnantc834c512011-11-29 18:15:50 +0000865template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000866void
Howard Hinnantc834c512011-11-29 18:15:50 +0000867__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000868{
869#ifndef _LIBCPP_NO_EXCEPTIONS
870 try
871 {
872#endif // _LIBCPP_NO_EXCEPTIONS
873 this->set_value(__func_());
874#ifndef _LIBCPP_NO_EXCEPTIONS
875 }
876 catch (...)
877 {
878 this->set_exception(current_exception());
879 }
880#endif // _LIBCPP_NO_EXCEPTIONS
881}
882
Howard Hinnantc834c512011-11-29 18:15:50 +0000883template <class _Fp>
884class __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000885 : public __assoc_sub_state
886{
887 typedef __assoc_sub_state base;
888
Howard Hinnantc834c512011-11-29 18:15:50 +0000889 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000890
891public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000892#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000893 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000894#endif
895
896 virtual void __execute();
897};
898
Howard Hinnant74279a52010-09-04 23:28:19 +0000899#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000900
Howard Hinnantc834c512011-11-29 18:15:50 +0000901template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000902inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000903__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
904 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000905{
906 this->__set_deferred();
907}
908
Howard Hinnant74279a52010-09-04 23:28:19 +0000909#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000910
Howard Hinnantc834c512011-11-29 18:15:50 +0000911template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000912void
Howard Hinnantc834c512011-11-29 18:15:50 +0000913__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000914{
915#ifndef _LIBCPP_NO_EXCEPTIONS
916 try
917 {
918#endif // _LIBCPP_NO_EXCEPTIONS
919 __func_();
920 this->set_value();
921#ifndef _LIBCPP_NO_EXCEPTIONS
922 }
923 catch (...)
924 {
925 this->set_exception(current_exception());
926 }
927#endif // _LIBCPP_NO_EXCEPTIONS
928}
929
Howard Hinnantc834c512011-11-29 18:15:50 +0000930template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000931class __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000932 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000933{
Howard Hinnantc834c512011-11-29 18:15:50 +0000934 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000935
Howard Hinnantc834c512011-11-29 18:15:50 +0000936 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000937
Howard Hinnant719bda32011-05-28 14:41:13 +0000938 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000939public:
940#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000941 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000942#endif
943
944 virtual void __execute();
945};
946
947#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
948
Howard Hinnantc834c512011-11-29 18:15:50 +0000949template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000950inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000951__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
952 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000953{
954}
955
956#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
957
Howard Hinnantc834c512011-11-29 18:15:50 +0000958template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000959void
Howard Hinnantc834c512011-11-29 18:15:50 +0000960__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000961{
962#ifndef _LIBCPP_NO_EXCEPTIONS
963 try
964 {
965#endif // _LIBCPP_NO_EXCEPTIONS
966 this->set_value(__func_());
967#ifndef _LIBCPP_NO_EXCEPTIONS
968 }
969 catch (...)
970 {
971 this->set_exception(current_exception());
972 }
973#endif // _LIBCPP_NO_EXCEPTIONS
974}
975
Howard Hinnantc834c512011-11-29 18:15:50 +0000976template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000977void
Howard Hinnantc834c512011-11-29 18:15:50 +0000978__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000979{
980 this->wait();
981 base::__on_zero_shared();
982}
983
Howard Hinnantc834c512011-11-29 18:15:50 +0000984template <class _Fp>
985class __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000986 : public __assoc_sub_state
987{
988 typedef __assoc_sub_state base;
989
Howard Hinnantc834c512011-11-29 18:15:50 +0000990 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000991
Howard Hinnant719bda32011-05-28 14:41:13 +0000992 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000993public:
994#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000995 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000996#endif
997
998 virtual void __execute();
999};
1000
1001#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1002
Howard Hinnantc834c512011-11-29 18:15:50 +00001003template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001004inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001005__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1006 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001007{
1008}
1009
1010#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1011
Howard Hinnantc834c512011-11-29 18:15:50 +00001012template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001013void
Howard Hinnantc834c512011-11-29 18:15:50 +00001014__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001015{
1016#ifndef _LIBCPP_NO_EXCEPTIONS
1017 try
1018 {
1019#endif // _LIBCPP_NO_EXCEPTIONS
1020 __func_();
1021 this->set_value();
1022#ifndef _LIBCPP_NO_EXCEPTIONS
1023 }
1024 catch (...)
1025 {
1026 this->set_exception(current_exception());
1027 }
1028#endif // _LIBCPP_NO_EXCEPTIONS
1029}
1030
Howard Hinnantc834c512011-11-29 18:15:50 +00001031template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001032void
Howard Hinnantc834c512011-11-29 18:15:50 +00001033__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001034{
1035 this->wait();
1036 base::__on_zero_shared();
1037}
1038
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001039template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1040template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001041
1042// future
1043
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001044template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001045
Howard Hinnantc834c512011-11-29 18:15:50 +00001046template <class _Rp, class _Fp>
1047future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001048#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001049__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001050#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001051__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001052#endif
1053
Howard Hinnantc834c512011-11-29 18:15:50 +00001054template <class _Rp, class _Fp>
1055future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001056#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001057__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001058#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001059__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001060#endif
1061
Howard Hinnantc834c512011-11-29 18:15:50 +00001062template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001063class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001064{
Howard Hinnantc834c512011-11-29 18:15:50 +00001065 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001066
Howard Hinnantc834c512011-11-29 18:15:50 +00001067 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001068
1069 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001070 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001071
Howard Hinnant74279a52010-09-04 23:28:19 +00001072#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001073 template <class _R1, class _Fp>
1074 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1075 template <class _R1, class _Fp>
1076 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001077#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001078 template <class _R1, class _Fp>
1079 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1080 template <class _R1, class _Fp>
1081 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001082#endif
1083
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001084public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001085 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001086 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001087#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001088 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001089 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001090 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1091 future(const future&) = delete;
1092 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001093 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001094 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001095 {
1096 future(std::move(__rhs)).swap(*this);
1097 return *this;
1098 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001099#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001100private:
1101 future(const future&);
1102 future& operator=(const future&);
1103public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001104#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001105 ~future();
Howard Hinnantc834c512011-11-29 18:15:50 +00001106 shared_future<_Rp> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001107
1108 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001109 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001110
Howard Hinnant684902d2010-09-22 14:16:26 +00001111 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001112 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001113
1114 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001115 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001116 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001117
Howard Hinnant684902d2010-09-22 14:16:26 +00001118 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001119 void wait() const {__state_->wait();}
1120 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001121 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001122 future_status
1123 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1124 {return __state_->wait_for(__rel_time);}
1125 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001126 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001127 future_status
1128 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1129 {return __state_->wait_until(__abs_time);}
1130};
1131
Howard Hinnantc834c512011-11-29 18:15:50 +00001132template <class _Rp>
1133future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001134 : __state_(__state)
1135{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001136#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001137 if (__state_->__has_future_attached())
1138 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001139#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001140 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001141 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001142}
1143
Howard Hinnantccdd2032010-08-30 18:46:21 +00001144struct __release_shared_count
1145{
1146 void operator()(__shared_count* p) {p->__release_shared();}
1147};
1148
Howard Hinnantc834c512011-11-29 18:15:50 +00001149template <class _Rp>
1150future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001151{
1152 if (__state_)
1153 __state_->__release_shared();
1154}
1155
Howard Hinnantc834c512011-11-29 18:15:50 +00001156template <class _Rp>
1157_Rp
1158future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001159{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001160 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001161 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001162 __state_ = nullptr;
1163 return __s->move();
1164}
1165
Howard Hinnantc834c512011-11-29 18:15:50 +00001166template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001167class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001168{
Howard Hinnantc834c512011-11-29 18:15:50 +00001169 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001170
Howard Hinnantc834c512011-11-29 18:15:50 +00001171 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001172
1173 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001174 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001175
Howard Hinnant74279a52010-09-04 23:28:19 +00001176#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001177 template <class _R1, class _Fp>
1178 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1179 template <class _R1, class _Fp>
1180 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001181#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001182 template <class _R1, class _Fp>
1183 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1184 template <class _R1, class _Fp>
1185 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001186#endif
1187
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001188public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001190 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001191#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001192 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001193 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001194 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1195 future(const future&) = delete;
1196 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001197 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001198 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001199 {
1200 future(std::move(__rhs)).swap(*this);
1201 return *this;
1202 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001203#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001204private:
1205 future(const future&);
1206 future& operator=(const future&);
1207public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001208#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001209 ~future();
Howard Hinnantc834c512011-11-29 18:15:50 +00001210 shared_future<_Rp&> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001211
1212 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001213 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001214
Howard Hinnant684902d2010-09-22 14:16:26 +00001215 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001216 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001217
1218 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001219 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001220 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001221
Howard Hinnant684902d2010-09-22 14:16:26 +00001222 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001223 void wait() const {__state_->wait();}
1224 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001226 future_status
1227 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1228 {return __state_->wait_for(__rel_time);}
1229 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001230 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001231 future_status
1232 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1233 {return __state_->wait_until(__abs_time);}
1234};
1235
Howard Hinnantc834c512011-11-29 18:15:50 +00001236template <class _Rp>
1237future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001238 : __state_(__state)
1239{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001240#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001241 if (__state_->__has_future_attached())
1242 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001243#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001244 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001245 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001246}
1247
Howard Hinnantc834c512011-11-29 18:15:50 +00001248template <class _Rp>
1249future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001250{
1251 if (__state_)
1252 __state_->__release_shared();
1253}
1254
Howard Hinnantc834c512011-11-29 18:15:50 +00001255template <class _Rp>
1256_Rp&
1257future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001258{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001259 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001260 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001261 __state_ = nullptr;
1262 return __s->copy();
1263}
1264
1265template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001266class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001267{
1268 __assoc_sub_state* __state_;
1269
1270 explicit future(__assoc_sub_state* __state);
1271
1272 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001273 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001274
Howard Hinnant74279a52010-09-04 23:28:19 +00001275#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001276 template <class _R1, class _Fp>
1277 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1278 template <class _R1, class _Fp>
1279 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001280#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001281 template <class _R1, class _Fp>
1282 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1283 template <class _R1, class _Fp>
1284 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001285#endif
1286
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001287public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001288 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001289 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001290#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001291 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001292 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001293 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1294 future(const future&) = delete;
1295 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001296 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001297 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001298 {
1299 future(std::move(__rhs)).swap(*this);
1300 return *this;
1301 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001302#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001303private:
1304 future(const future&);
1305 future& operator=(const future&);
1306public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001307#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001308 ~future();
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001309 shared_future<void> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001310
1311 // retrieving the value
1312 void get();
1313
Howard Hinnant684902d2010-09-22 14:16:26 +00001314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001315 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001316
1317 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001319 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001320
Howard Hinnant684902d2010-09-22 14:16:26 +00001321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001322 void wait() const {__state_->wait();}
1323 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001324 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001325 future_status
1326 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1327 {return __state_->wait_for(__rel_time);}
1328 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001330 future_status
1331 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1332 {return __state_->wait_until(__abs_time);}
1333};
1334
Howard Hinnantc834c512011-11-29 18:15:50 +00001335template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001336inline _LIBCPP_INLINE_VISIBILITY
1337void
Howard Hinnant22448042012-07-21 17:46:55 +00001338swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001339{
1340 __x.swap(__y);
1341}
1342
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001343// promise<R>
1344
Howard Hinnant944510a2011-06-14 19:58:17 +00001345template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001346
Howard Hinnantc834c512011-11-29 18:15:50 +00001347template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001348class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001349{
Howard Hinnantc834c512011-11-29 18:15:50 +00001350 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001351
Howard Hinnant684902d2010-09-22 14:16:26 +00001352 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001353 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001354
1355 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001356public:
1357 promise();
1358 template <class _Alloc>
1359 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001360#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001361 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001362 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001363 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1364 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001365#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001366private:
1367 promise(const promise& __rhs);
1368public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001369#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001370 ~promise();
1371
1372 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001373#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001375 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001376 {
1377 promise(std::move(__rhs)).swap(*this);
1378 return *this;
1379 }
1380 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001381#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001382private:
1383 promise& operator=(const promise& __rhs);
1384public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001385#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001386 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001387 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001388
1389 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001390 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001391
1392 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001393 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001394#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001395 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001396#endif
1397 void set_exception(exception_ptr __p);
1398
1399 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001400 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001401#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001402 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001403#endif
1404 void set_exception_at_thread_exit(exception_ptr __p);
1405};
1406
Howard Hinnantc834c512011-11-29 18:15:50 +00001407template <class _Rp>
1408promise<_Rp>::promise()
1409 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001410{
1411}
1412
Howard Hinnantc834c512011-11-29 18:15:50 +00001413template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001414template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001415promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001416{
Howard Hinnantc834c512011-11-29 18:15:50 +00001417 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001418 typedef __allocator_destructor<_A2> _D2;
1419 _A2 __a(__a0);
Howard Hinnantc834c512011-11-29 18:15:50 +00001420 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1421 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001422 __state_ = __hold.release();
1423}
1424
Howard Hinnantc834c512011-11-29 18:15:50 +00001425template <class _Rp>
1426promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001427{
1428 if (__state_)
1429 {
1430 if (!__state_->__has_value() && __state_->use_count() > 1)
1431 __state_->set_exception(make_exception_ptr(
1432 future_error(make_error_code(future_errc::broken_promise))
1433 ));
1434 __state_->__release_shared();
1435 }
1436}
1437
Howard Hinnantc834c512011-11-29 18:15:50 +00001438template <class _Rp>
1439future<_Rp>
1440promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001441{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001442#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001443 if (__state_ == nullptr)
1444 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001445#endif
Howard Hinnantc834c512011-11-29 18:15:50 +00001446 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001447}
1448
Howard Hinnantc834c512011-11-29 18:15:50 +00001449template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001450void
Howard Hinnantc834c512011-11-29 18:15:50 +00001451promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001452{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001453#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001454 if (__state_ == nullptr)
1455 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001456#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001457 __state_->set_value(__r);
1458}
1459
Howard Hinnant74279a52010-09-04 23:28:19 +00001460#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001461
Howard Hinnantc834c512011-11-29 18:15:50 +00001462template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001463void
Howard Hinnantc834c512011-11-29 18:15:50 +00001464promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001465{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001466#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001467 if (__state_ == nullptr)
1468 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001469#endif
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001470 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001471}
1472
Howard Hinnant74279a52010-09-04 23:28:19 +00001473#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001474
Howard Hinnantc834c512011-11-29 18:15:50 +00001475template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001476void
Howard Hinnantc834c512011-11-29 18:15:50 +00001477promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001478{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001479#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001480 if (__state_ == nullptr)
1481 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001482#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001483 __state_->set_exception(__p);
1484}
1485
Howard Hinnantc834c512011-11-29 18:15:50 +00001486template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001487void
Howard Hinnantc834c512011-11-29 18:15:50 +00001488promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001489{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001490#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001491 if (__state_ == nullptr)
1492 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001493#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001494 __state_->set_value_at_thread_exit(__r);
1495}
1496
Howard Hinnant74279a52010-09-04 23:28:19 +00001497#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001498
Howard Hinnantc834c512011-11-29 18:15:50 +00001499template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001500void
Howard Hinnantc834c512011-11-29 18:15:50 +00001501promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001502{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001503#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504 if (__state_ == nullptr)
1505 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001506#endif
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001507 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001508}
1509
Howard Hinnant74279a52010-09-04 23:28:19 +00001510#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001511
Howard Hinnantc834c512011-11-29 18:15:50 +00001512template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001513void
Howard Hinnantc834c512011-11-29 18:15:50 +00001514promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001515{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001516#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001517 if (__state_ == nullptr)
1518 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001519#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001520 __state_->set_exception_at_thread_exit(__p);
1521}
1522
1523// promise<R&>
1524
Howard Hinnantc834c512011-11-29 18:15:50 +00001525template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001526class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001527{
Howard Hinnantc834c512011-11-29 18:15:50 +00001528 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001529
Howard Hinnant684902d2010-09-22 14:16:26 +00001530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001531 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001532
1533 template <class> friend class packaged_task;
1534
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001535public:
1536 promise();
1537 template <class _Allocator>
1538 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001539#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001541 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001542 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1543 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001544#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001545private:
1546 promise(const promise& __rhs);
1547public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001548#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001549 ~promise();
1550
1551 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001552#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001553 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001554 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001555 {
1556 promise(std::move(__rhs)).swap(*this);
1557 return *this;
1558 }
1559 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001560#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001561private:
1562 promise& operator=(const promise& __rhs);
1563public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001564#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001566 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001567
1568 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001569 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001570
1571 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001572 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001573 void set_exception(exception_ptr __p);
1574
1575 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001576 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001577 void set_exception_at_thread_exit(exception_ptr __p);
1578};
1579
Howard Hinnantc834c512011-11-29 18:15:50 +00001580template <class _Rp>
1581promise<_Rp&>::promise()
1582 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001583{
1584}
1585
Howard Hinnantc834c512011-11-29 18:15:50 +00001586template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001587template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001588promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001589{
Howard Hinnantc834c512011-11-29 18:15:50 +00001590 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001591 typedef __allocator_destructor<_A2> _D2;
1592 _A2 __a(__a0);
Howard Hinnantc834c512011-11-29 18:15:50 +00001593 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1594 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001595 __state_ = __hold.release();
1596}
1597
Howard Hinnantc834c512011-11-29 18:15:50 +00001598template <class _Rp>
1599promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001600{
1601 if (__state_)
1602 {
1603 if (!__state_->__has_value() && __state_->use_count() > 1)
1604 __state_->set_exception(make_exception_ptr(
1605 future_error(make_error_code(future_errc::broken_promise))
1606 ));
1607 __state_->__release_shared();
1608 }
1609}
1610
Howard Hinnantc834c512011-11-29 18:15:50 +00001611template <class _Rp>
1612future<_Rp&>
1613promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001614{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001615#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001616 if (__state_ == nullptr)
1617 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001618#endif
Howard Hinnantc834c512011-11-29 18:15:50 +00001619 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001620}
1621
Howard Hinnantc834c512011-11-29 18:15:50 +00001622template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001623void
Howard Hinnantc834c512011-11-29 18:15:50 +00001624promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001625{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001626#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001627 if (__state_ == nullptr)
1628 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001629#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001630 __state_->set_value(__r);
1631}
1632
Howard Hinnantc834c512011-11-29 18:15:50 +00001633template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001634void
Howard Hinnantc834c512011-11-29 18:15:50 +00001635promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001636{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001637#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001638 if (__state_ == nullptr)
1639 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001640#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001641 __state_->set_exception(__p);
1642}
1643
Howard Hinnantc834c512011-11-29 18:15:50 +00001644template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001645void
Howard Hinnantc834c512011-11-29 18:15:50 +00001646promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001647{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001648#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001649 if (__state_ == nullptr)
1650 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001651#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001652 __state_->set_value_at_thread_exit(__r);
1653}
1654
Howard Hinnantc834c512011-11-29 18:15:50 +00001655template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001656void
Howard Hinnantc834c512011-11-29 18:15:50 +00001657promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001658{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001659#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001660 if (__state_ == nullptr)
1661 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001662#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001663 __state_->set_exception_at_thread_exit(__p);
1664}
1665
1666// promise<void>
1667
1668template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001669class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001670{
1671 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001672
Howard Hinnant684902d2010-09-22 14:16:26 +00001673 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001674 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001675
1676 template <class> friend class packaged_task;
1677
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001678public:
1679 promise();
1680 template <class _Allocator>
1681 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001682#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001683 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001684 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001685 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1686 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001687#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001688private:
1689 promise(const promise& __rhs);
1690public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001691#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001692 ~promise();
1693
1694 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001695#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001696 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001697 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001698 {
1699 promise(std::move(__rhs)).swap(*this);
1700 return *this;
1701 }
1702 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001703#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001704private:
1705 promise& operator=(const promise& __rhs);
1706public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001707#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001709 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001710
1711 // retrieving the result
1712 future<void> get_future();
1713
1714 // setting the result
1715 void set_value();
1716 void set_exception(exception_ptr __p);
1717
1718 // setting the result with deferred notification
1719 void set_value_at_thread_exit();
1720 void set_exception_at_thread_exit(exception_ptr __p);
1721};
1722
1723template <class _Alloc>
1724promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1725{
1726 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1727 typedef __allocator_destructor<_A2> _D2;
1728 _A2 __a(__a0);
1729 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1730 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1731 __state_ = __hold.release();
1732}
1733
Howard Hinnantc834c512011-11-29 18:15:50 +00001734template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001735inline _LIBCPP_INLINE_VISIBILITY
1736void
Howard Hinnant22448042012-07-21 17:46:55 +00001737swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001738{
1739 __x.swap(__y);
1740}
1741
Howard Hinnantc834c512011-11-29 18:15:50 +00001742template <class _Rp, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001743 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001744 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001745
Howard Hinnantccdd2032010-08-30 18:46:21 +00001746#ifndef _LIBCPP_HAS_NO_VARIADICS
1747
1748// packaged_task
1749
1750template<class _Fp> class __packaged_task_base;
1751
Howard Hinnantc834c512011-11-29 18:15:50 +00001752template<class _Rp, class ..._ArgTypes>
1753class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001754{
1755 __packaged_task_base(const __packaged_task_base&);
1756 __packaged_task_base& operator=(const __packaged_task_base&);
1757public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001759 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001760 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001761 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001762 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001763 virtual void destroy() = 0;
1764 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001765 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001766};
1767
1768template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1769
Howard Hinnantc834c512011-11-29 18:15:50 +00001770template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1771class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1772 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001773{
Howard Hinnantc834c512011-11-29 18:15:50 +00001774 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001775public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001777 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001779 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001781 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001782 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001784 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001785 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001786 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001787 virtual void destroy();
1788 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001789 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001790};
1791
Howard Hinnantc834c512011-11-29 18:15:50 +00001792template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001793void
Howard Hinnantc834c512011-11-29 18:15:50 +00001794__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001795 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001796{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001797 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001798}
1799
Howard Hinnantc834c512011-11-29 18:15:50 +00001800template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001801void
Howard Hinnantc834c512011-11-29 18:15:50 +00001802__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001803{
Howard Hinnantc834c512011-11-29 18:15:50 +00001804 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001805}
1806
Howard Hinnantc834c512011-11-29 18:15:50 +00001807template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001808void
Howard Hinnantc834c512011-11-29 18:15:50 +00001809__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001810{
Howard Hinnantc834c512011-11-29 18:15:50 +00001811 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1812 _Ap __a(__f_.second());
1813 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001814 __a.deallocate(this, 1);
1815}
1816
Howard Hinnantc834c512011-11-29 18:15:50 +00001817template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1818_Rp
1819__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001820{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001821 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001822}
1823
Howard Hinnant944510a2011-06-14 19:58:17 +00001824template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001825
Howard Hinnantc834c512011-11-29 18:15:50 +00001826template<class _Rp, class ..._ArgTypes>
1827class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001828{
Howard Hinnantc834c512011-11-29 18:15:50 +00001829 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001830 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001831 __base* __f_;
1832
1833public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001834 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001835
1836 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001837 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001838 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001839 template<class _Fp>
1840 __packaged_task_function(_Fp&& __f);
1841 template<class _Fp, class _Alloc>
1842 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001843
Howard Hinnant22448042012-07-21 17:46:55 +00001844 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1845 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001846
1847 __packaged_task_function(const __packaged_task_function&) = delete;
1848 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1849
1850 ~__packaged_task_function();
1851
Howard Hinnant22448042012-07-21 17:46:55 +00001852 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001853
Howard Hinnantc834c512011-11-29 18:15:50 +00001854 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001855};
1856
Howard Hinnantc834c512011-11-29 18:15:50 +00001857template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001858__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001859{
1860 if (__f.__f_ == nullptr)
1861 __f_ = nullptr;
1862 else if (__f.__f_ == (__base*)&__f.__buf_)
1863 {
1864 __f_ = (__base*)&__buf_;
1865 __f.__f_->__move_to(__f_);
1866 }
1867 else
1868 {
1869 __f_ = __f.__f_;
1870 __f.__f_ = nullptr;
1871 }
1872}
1873
Howard Hinnantc834c512011-11-29 18:15:50 +00001874template<class _Rp, class ..._ArgTypes>
1875template <class _Fp>
1876__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001877 : __f_(nullptr)
1878{
Marshall Clow733d60e2014-04-07 13:32:26 +00001879 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001880 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001881 if (sizeof(_FF) <= sizeof(__buf_))
1882 {
1883 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001884 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001885 }
1886 else
1887 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001888 typedef allocator<_FF> _Ap;
1889 _Ap __a;
1890 typedef __allocator_destructor<_Ap> _Dp;
1891 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1892 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001893 __f_ = __hold.release();
1894 }
1895}
1896
Howard Hinnantc834c512011-11-29 18:15:50 +00001897template<class _Rp, class ..._ArgTypes>
1898template <class _Fp, class _Alloc>
1899__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1900 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001901 : __f_(nullptr)
1902{
1903 typedef allocator_traits<_Alloc> __alloc_traits;
Marshall Clow733d60e2014-04-07 13:32:26 +00001904 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001905 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001906 if (sizeof(_FF) <= sizeof(__buf_))
1907 {
1908 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001909 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001910 }
1911 else
1912 {
1913 typedef typename __alloc_traits::template
1914#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1915 rebind_alloc<_FF>
1916#else
1917 rebind_alloc<_FF>::other
1918#endif
Howard Hinnantc834c512011-11-29 18:15:50 +00001919 _Ap;
1920 _Ap __a(__a0);
1921 typedef __allocator_destructor<_Ap> _Dp;
1922 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1923 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001924 __f_ = __hold.release();
1925 }
1926}
1927
Howard Hinnantc834c512011-11-29 18:15:50 +00001928template<class _Rp, class ..._ArgTypes>
1929__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001930__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001931{
1932 if (__f_ == (__base*)&__buf_)
1933 __f_->destroy();
1934 else if (__f_)
1935 __f_->destroy_deallocate();
1936 __f_ = nullptr;
1937 if (__f.__f_ == nullptr)
1938 __f_ = nullptr;
1939 else if (__f.__f_ == (__base*)&__f.__buf_)
1940 {
1941 __f_ = (__base*)&__buf_;
1942 __f.__f_->__move_to(__f_);
1943 }
1944 else
1945 {
1946 __f_ = __f.__f_;
1947 __f.__f_ = nullptr;
1948 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001949 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001950}
1951
Howard Hinnantc834c512011-11-29 18:15:50 +00001952template<class _Rp, class ..._ArgTypes>
1953__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001954{
1955 if (__f_ == (__base*)&__buf_)
1956 __f_->destroy();
1957 else if (__f_)
1958 __f_->destroy_deallocate();
1959}
1960
Howard Hinnantc834c512011-11-29 18:15:50 +00001961template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001962void
Howard Hinnant22448042012-07-21 17:46:55 +00001963__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001964{
1965 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1966 {
1967 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1968 __base* __t = (__base*)&__tempbuf;
1969 __f_->__move_to(__t);
1970 __f_->destroy();
1971 __f_ = nullptr;
1972 __f.__f_->__move_to((__base*)&__buf_);
1973 __f.__f_->destroy();
1974 __f.__f_ = nullptr;
1975 __f_ = (__base*)&__buf_;
1976 __t->__move_to((__base*)&__f.__buf_);
1977 __t->destroy();
1978 __f.__f_ = (__base*)&__f.__buf_;
1979 }
1980 else if (__f_ == (__base*)&__buf_)
1981 {
1982 __f_->__move_to((__base*)&__f.__buf_);
1983 __f_->destroy();
1984 __f_ = __f.__f_;
1985 __f.__f_ = (__base*)&__f.__buf_;
1986 }
1987 else if (__f.__f_ == (__base*)&__f.__buf_)
1988 {
1989 __f.__f_->__move_to((__base*)&__buf_);
1990 __f.__f_->destroy();
1991 __f.__f_ = __f_;
1992 __f_ = (__base*)&__buf_;
1993 }
1994 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001995 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001996}
1997
Howard Hinnantc834c512011-11-29 18:15:50 +00001998template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001999inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002000_Rp
2001__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00002002{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002003 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004}
2005
Howard Hinnantc834c512011-11-29 18:15:50 +00002006template<class _Rp, class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002007class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002008{
2009public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002010 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002011
2012private:
2013 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2014 promise<result_type> __p_;
2015
2016public:
2017 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002018 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002019 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002020 template <class _Fp,
2021 class = typename enable_if
2022 <
2023 !is_same<
2024 typename decay<_Fp>::type,
2025 packaged_task
2026 >::value
2027 >::type
2028 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002029 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002030 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002031 template <class _Fp, class _Allocator,
2032 class = typename enable_if
2033 <
2034 !is_same<
2035 typename decay<_Fp>::type,
2036 packaged_task
2037 >::value
2038 >::type
2039 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002040 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002041 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2042 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002043 __p_(allocator_arg, __a) {}
2044 // ~packaged_task() = default;
2045
2046 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002047 packaged_task(const packaged_task&) = delete;
2048 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002049
2050 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002052 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002053 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002055 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002056 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002057 __f_ = _VSTD::move(__other.__f_);
2058 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002059 return *this;
2060 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002062 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002063 {
2064 __f_.swap(__other.__f_);
2065 __p_.swap(__other.__p_);
2066 }
2067
Howard Hinnant684902d2010-09-22 14:16:26 +00002068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002069 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002070
2071 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002072 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002073 future<result_type> get_future() {return __p_.get_future();}
2074
2075 // execution
2076 void operator()(_ArgTypes... __args);
2077 void make_ready_at_thread_exit(_ArgTypes... __args);
2078
2079 void reset();
2080};
2081
Howard Hinnantc834c512011-11-29 18:15:50 +00002082template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002083void
Howard Hinnantc834c512011-11-29 18:15:50 +00002084packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002085{
2086#ifndef _LIBCPP_NO_EXCEPTIONS
2087 if (__p_.__state_ == nullptr)
2088 throw future_error(make_error_code(future_errc::no_state));
2089 if (__p_.__state_->__has_value())
2090 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2091 try
2092 {
2093#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002094 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002095#ifndef _LIBCPP_NO_EXCEPTIONS
2096 }
2097 catch (...)
2098 {
2099 __p_.set_exception(current_exception());
2100 }
2101#endif // _LIBCPP_NO_EXCEPTIONS
2102}
2103
Howard Hinnantc834c512011-11-29 18:15:50 +00002104template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002105void
Howard Hinnantc834c512011-11-29 18:15:50 +00002106packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002107{
2108#ifndef _LIBCPP_NO_EXCEPTIONS
2109 if (__p_.__state_ == nullptr)
2110 throw future_error(make_error_code(future_errc::no_state));
2111 if (__p_.__state_->__has_value())
2112 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2113 try
2114 {
2115#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002116 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002117#ifndef _LIBCPP_NO_EXCEPTIONS
2118 }
2119 catch (...)
2120 {
2121 __p_.set_exception_at_thread_exit(current_exception());
2122 }
2123#endif // _LIBCPP_NO_EXCEPTIONS
2124}
2125
Howard Hinnantc834c512011-11-29 18:15:50 +00002126template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002127void
Howard Hinnantc834c512011-11-29 18:15:50 +00002128packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002129{
2130#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002131 if (!valid())
Howard Hinnantccdd2032010-08-30 18:46:21 +00002132 throw future_error(make_error_code(future_errc::no_state));
2133#endif // _LIBCPP_NO_EXCEPTIONS
2134 __p_ = promise<result_type>();
2135}
2136
2137template<class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002138class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002139{
2140public:
2141 typedef void result_type;
2142
2143private:
2144 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2145 promise<result_type> __p_;
2146
2147public:
2148 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002149 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002150 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002151 template <class _Fp,
2152 class = typename enable_if
2153 <
2154 !is_same<
2155 typename decay<_Fp>::type,
2156 packaged_task
2157 >::value
2158 >::type
2159 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002160 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002161 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002162 template <class _Fp, class _Allocator,
2163 class = typename enable_if
2164 <
2165 !is_same<
2166 typename decay<_Fp>::type,
2167 packaged_task
2168 >::value
2169 >::type
2170 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002171 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002172 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2173 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002174 __p_(allocator_arg, __a) {}
2175 // ~packaged_task() = default;
2176
2177 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002178 packaged_task(const packaged_task&) = delete;
2179 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002180
2181 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002182 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002183 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002184 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002185 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002186 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002187 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002188 __f_ = _VSTD::move(__other.__f_);
2189 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002190 return *this;
2191 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002192 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002193 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002194 {
2195 __f_.swap(__other.__f_);
2196 __p_.swap(__other.__p_);
2197 }
2198
Howard Hinnant684902d2010-09-22 14:16:26 +00002199 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002200 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002201
2202 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002203 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002204 future<result_type> get_future() {return __p_.get_future();}
2205
2206 // execution
2207 void operator()(_ArgTypes... __args);
2208 void make_ready_at_thread_exit(_ArgTypes... __args);
2209
2210 void reset();
2211};
2212
2213template<class ..._ArgTypes>
2214void
2215packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2216{
2217#ifndef _LIBCPP_NO_EXCEPTIONS
2218 if (__p_.__state_ == nullptr)
2219 throw future_error(make_error_code(future_errc::no_state));
2220 if (__p_.__state_->__has_value())
2221 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2222 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();
2227#ifndef _LIBCPP_NO_EXCEPTIONS
2228 }
2229 catch (...)
2230 {
2231 __p_.set_exception(current_exception());
2232 }
2233#endif // _LIBCPP_NO_EXCEPTIONS
2234}
2235
2236template<class ..._ArgTypes>
2237void
2238packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2239{
2240#ifndef _LIBCPP_NO_EXCEPTIONS
2241 if (__p_.__state_ == nullptr)
2242 throw future_error(make_error_code(future_errc::no_state));
2243 if (__p_.__state_->__has_value())
2244 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2245 try
2246 {
2247#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002248 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002249 __p_.set_value_at_thread_exit();
2250#ifndef _LIBCPP_NO_EXCEPTIONS
2251 }
2252 catch (...)
2253 {
2254 __p_.set_exception_at_thread_exit(current_exception());
2255 }
2256#endif // _LIBCPP_NO_EXCEPTIONS
2257}
2258
2259template<class ..._ArgTypes>
2260void
2261packaged_task<void(_ArgTypes...)>::reset()
2262{
2263#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002264 if (!valid())
Howard Hinnantccdd2032010-08-30 18:46:21 +00002265 throw future_error(make_error_code(future_errc::no_state));
2266#endif // _LIBCPP_NO_EXCEPTIONS
2267 __p_ = promise<result_type>();
2268}
2269
2270template <class _Callable>
2271inline _LIBCPP_INLINE_VISIBILITY
2272void
Howard Hinnant22448042012-07-21 17:46:55 +00002273swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002274{
2275 __x.swap(__y);
2276}
2277
2278template <class _Callable, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002279struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00002280 : public true_type {};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002281
Howard Hinnantc834c512011-11-29 18:15:50 +00002282template <class _Rp, class _Fp>
2283future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002284#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002285__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002286#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002287__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002288#endif
2289{
Howard Hinnantc834c512011-11-29 18:15:50 +00002290 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2291 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2292 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002293}
2294
Howard Hinnantc834c512011-11-29 18:15:50 +00002295template <class _Rp, class _Fp>
2296future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002297#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002298__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002299#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002300__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002301#endif
2302{
Howard Hinnantc834c512011-11-29 18:15:50 +00002303 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2304 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2305 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2306 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002307}
2308
Howard Hinnantc834c512011-11-29 18:15:50 +00002309template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002310class __async_func
2311{
Howard Hinnantc834c512011-11-29 18:15:50 +00002312 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002313
2314public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002315 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002316
2317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002318 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002319 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002320
2321 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002322 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002323
Howard Hinnantc834c512011-11-29 18:15:50 +00002324 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002325 {
2326 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2327 return __execute(_Index());
2328 }
2329private:
2330 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002331 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002332 __execute(__tuple_indices<_Indices...>)
2333 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002334 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002335 }
2336};
2337
Marshall Clowd56a5b62013-11-03 22:06:53 +00002338inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002339{ return (int(__policy) & int(__value)) != 0; }
2340
Howard Hinnantc834c512011-11-29 18:15:50 +00002341template <class _Fp, class... _Args>
2342future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2343async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002344{
Howard Hinnantc834c512011-11-29 18:15:50 +00002345 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2346 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002347
2348#ifndef _LIBCPP_NO_EXCEPTIONS
2349 try
2350 {
2351#endif
2352 if (__does_policy_contain(__policy, launch::async))
2353 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002354 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002355#ifndef _LIBCPP_NO_EXCEPTIONS
2356 }
2357 catch ( ... ) { if (__policy == launch::async) throw ; }
2358#endif
2359
2360 if (__does_policy_contain(__policy, launch::deferred))
2361 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002362 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002363 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002364}
2365
Howard Hinnantc834c512011-11-29 18:15:50 +00002366template <class _Fp, class... _Args>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002367inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002368future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2369async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002370{
Howard Hinnantc834c512011-11-29 18:15:50 +00002371 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002372 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002373}
2374
2375#endif // _LIBCPP_HAS_NO_VARIADICS
2376
Howard Hinnante6a10852010-09-03 21:46:37 +00002377// shared_future
2378
Howard Hinnantc834c512011-11-29 18:15:50 +00002379template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002380class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002381{
Howard Hinnantc834c512011-11-29 18:15:50 +00002382 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002383
2384public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002386 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002388 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2389 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002390#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002392 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002393 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002395 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002396 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002397#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002398 ~shared_future();
2399 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002400#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002402 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002403 {
2404 shared_future(std::move(__rhs)).swap(*this);
2405 return *this;
2406 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002407#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002408
2409 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002411 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002412
Howard Hinnant684902d2010-09-22 14:16:26 +00002413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002414 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002415
2416 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002418 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002419
Howard Hinnant684902d2010-09-22 14:16:26 +00002420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002421 void wait() const {__state_->wait();}
2422 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002424 future_status
2425 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2426 {return __state_->wait_for(__rel_time);}
2427 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002428 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002429 future_status
2430 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2431 {return __state_->wait_until(__abs_time);}
2432};
2433
Howard Hinnantc834c512011-11-29 18:15:50 +00002434template <class _Rp>
2435shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002436{
2437 if (__state_)
2438 __state_->__release_shared();
2439}
2440
Howard Hinnantc834c512011-11-29 18:15:50 +00002441template <class _Rp>
2442shared_future<_Rp>&
2443shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002444{
2445 if (__rhs.__state_)
2446 __rhs.__state_->__add_shared();
2447 if (__state_)
2448 __state_->__release_shared();
2449 __state_ = __rhs.__state_;
2450 return *this;
2451}
2452
Howard Hinnantc834c512011-11-29 18:15:50 +00002453template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002454class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002455{
Howard Hinnantc834c512011-11-29 18:15:50 +00002456 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002457
2458public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002459 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002460 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002461 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002462 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2463 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002464#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002466 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002467 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002469 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002470 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002471#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002472 ~shared_future();
2473 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002474#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002475 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002476 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002477 {
2478 shared_future(std::move(__rhs)).swap(*this);
2479 return *this;
2480 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002481#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002482
2483 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002485 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002486
Howard Hinnant684902d2010-09-22 14:16:26 +00002487 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002488 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002489
2490 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002491 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002492 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002493
Howard Hinnant684902d2010-09-22 14:16:26 +00002494 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002495 void wait() const {__state_->wait();}
2496 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002497 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002498 future_status
2499 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2500 {return __state_->wait_for(__rel_time);}
2501 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002502 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002503 future_status
2504 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2505 {return __state_->wait_until(__abs_time);}
2506};
2507
Howard Hinnantc834c512011-11-29 18:15:50 +00002508template <class _Rp>
2509shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002510{
2511 if (__state_)
2512 __state_->__release_shared();
2513}
2514
Howard Hinnantc834c512011-11-29 18:15:50 +00002515template <class _Rp>
2516shared_future<_Rp&>&
2517shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002518{
2519 if (__rhs.__state_)
2520 __rhs.__state_->__add_shared();
2521 if (__state_)
2522 __state_->__release_shared();
2523 __state_ = __rhs.__state_;
2524 return *this;
2525}
2526
2527template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00002528class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002529{
2530 __assoc_sub_state* __state_;
2531
2532public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002534 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002536 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2537 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002538#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002540 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002541 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002543 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002544 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002545#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002546 ~shared_future();
2547 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002548#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002550 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002551 {
2552 shared_future(std::move(__rhs)).swap(*this);
2553 return *this;
2554 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002555#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002556
2557 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002559 void get() const {__state_->copy();}
2560
Howard Hinnant684902d2010-09-22 14:16:26 +00002561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002562 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002563
2564 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002565 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002566 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002567
Howard Hinnant684902d2010-09-22 14:16:26 +00002568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002569 void wait() const {__state_->wait();}
2570 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002571 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002572 future_status
2573 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2574 {return __state_->wait_for(__rel_time);}
2575 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002577 future_status
2578 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2579 {return __state_->wait_until(__abs_time);}
2580};
2581
Howard Hinnantc834c512011-11-29 18:15:50 +00002582template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002583inline _LIBCPP_INLINE_VISIBILITY
2584void
Howard Hinnant22448042012-07-21 17:46:55 +00002585swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002586{
2587 __x.swap(__y);
2588}
2589
Howard Hinnantc834c512011-11-29 18:15:50 +00002590template <class _Rp>
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002591inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002592shared_future<_Rp>
2593future<_Rp>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002594{
Howard Hinnantc834c512011-11-29 18:15:50 +00002595 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002596}
2597
Howard Hinnantc834c512011-11-29 18:15:50 +00002598template <class _Rp>
Howard Hinnante6a10852010-09-03 21:46:37 +00002599inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002600shared_future<_Rp&>
2601future<_Rp&>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002602{
Howard Hinnantc834c512011-11-29 18:15:50 +00002603 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002604}
2605
Howard Hinnante65e8e32010-12-02 16:45:21 +00002606#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2607
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002608inline _LIBCPP_INLINE_VISIBILITY
2609shared_future<void>
2610future<void>::share()
2611{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002612 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002613}
2614
Howard Hinnante65e8e32010-12-02 16:45:21 +00002615#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2616
Howard Hinnantc51e1022010-05-11 19:42:16 +00002617_LIBCPP_END_NAMESPACE_STD
2618
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002619#endif // !_LIBCPP_HAS_NO_THREADS
2620
Howard Hinnantc51e1022010-05-11 19:42:16 +00002621#endif // _LIBCPP_FUTURE