blob: 39475bd955c8ee6f104c89db08220b8f786915d5 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
22 broken_promise,
23 future_already_retrieved,
24 promise_already_satisfied,
25 no_state
26};
27
28enum class launch
29{
Howard Hinnant66895642010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000033};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000045
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000056};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000073
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000311template <class F, class... Args>
312 future<typename result_of<F(Args...)>::type>
313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
316 future<typename result_of<F(Args...)>::type>
317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantf5256e12010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
325 typedef R result_type;
326
327 // construction and destruction
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
332 explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333 ~packaged_task();
334
335 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000340 packaged_task(packaged_task&& other) noexcept;
341 packaged_task& operator=(packaged_task&& other) noexcept;
342 void swap(packaged_task& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000343
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000358
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant47499b12010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372
Howard Hinnant08e17472011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000375#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376
377_LIBCPP_BEGIN_NAMESPACE_STD
378
379//enum class future_errc
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000380_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000382 broken_promise,
383 future_already_retrieved,
384 promise_already_satisfied,
385 no_state
386};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000387_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000388
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000389template <>
390struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000391
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000392#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
393template <>
394struct _LIBCPP_VISIBLE is_error_code_enum<future_errc::_> : public true_type { };
395#endif
396
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397//enum class launch
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000398_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000399{
Howard Hinnant66895642010-11-23 18:33:54 +0000400 async = 1,
401 deferred = 2,
402 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000404_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405
406//enum class future_status
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000407_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000408{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409 ready,
410 timeout,
411 deferred
412};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000413_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000415_LIBCPP_VISIBLE
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000416const error_category& future_category() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000417
418inline _LIBCPP_INLINE_VISIBILITY
419error_code
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000420make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000421{
422 return error_code(static_cast<int>(__e), future_category());
423}
424
425inline _LIBCPP_INLINE_VISIBILITY
426error_condition
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000427make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000428{
429 return error_condition(static_cast<int>(__e), future_category());
430}
431
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000432class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000433 : public logic_error
434{
435 error_code __ec_;
436public:
437 future_error(error_code __ec);
438
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000440 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52 +0000441
442 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000443};
444
Howard Hinnant47499b12010-08-27 20:10:19 +0000445class __assoc_sub_state
446 : public __shared_count
447{
448protected:
449 exception_ptr __exception_;
450 mutable mutex __mut_;
451 mutable condition_variable __cv_;
452 unsigned __state_;
453
Howard Hinnant1694d232011-05-28 14:41:13 +0000454 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000455 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000456public:
457 enum
458 {
459 __constructed = 1,
460 __future_attached = 2,
461 ready = 4,
462 deferred = 8
463 };
464
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000466 __assoc_sub_state() : __state_(0) {}
467
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000469 bool __has_value() const
470 {return (__state_ & __constructed) || (__exception_ != nullptr);}
471
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000473 void __set_future_attached() {__state_ |= __future_attached;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000475 bool __has_future_attached() const {return __state_ & __future_attached;}
476
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000478 void __set_deferred() {__state_ |= deferred;}
479
Howard Hinnant47499b12010-08-27 20:10:19 +0000480 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000482 bool __is_ready() const {return __state_ & ready;}
483
484 void set_value();
485 void set_value_at_thread_exit();
486
487 void set_exception(exception_ptr __p);
488 void set_exception_at_thread_exit(exception_ptr __p);
489
490 void copy();
491
Howard Hinnant54da3382010-08-30 18:46:21 +0000492 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000493 template <class _Rep, class _Period>
494 future_status
495 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
496 template <class _Clock, class _Duration>
497 future_status
498 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000499
500 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000501};
502
Howard Hinnantf39daa82010-08-28 21:01:06 +0000503template <class _Clock, class _Duration>
504future_status
505__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
506{
507 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000508 if (__state_ & deferred)
509 return future_status::deferred;
510 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000511 __cv_.wait_until(__lk, __abs_time);
512 if (__state_ & ready)
513 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000514 return future_status::timeout;
515}
516
517template <class _Rep, class _Period>
518inline _LIBCPP_INLINE_VISIBILITY
519future_status
520__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
521{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000522 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000523}
524
Howard Hinnant99968442011-11-29 18:15:50 +0000525template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000526class __assoc_state
527 : public __assoc_sub_state
528{
529 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000530 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000531protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000532 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000533
Howard Hinnant1694d232011-05-28 14:41:13 +0000534 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000535public:
536
537 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000538#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000539 void set_value(_Arg&& __arg);
540#else
541 void set_value(_Arg& __arg);
542#endif
543
544 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000545#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000546 void set_value_at_thread_exit(_Arg&& __arg);
547#else
548 void set_value_at_thread_exit(_Arg& __arg);
549#endif
550
Howard Hinnant99968442011-11-29 18:15:50 +0000551 _Rp move();
552 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000553};
554
Howard Hinnant99968442011-11-29 18:15:50 +0000555template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000556void
Howard Hinnant99968442011-11-29 18:15:50 +0000557__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000558{
559 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000560 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000561 delete this;
562}
563
Howard Hinnant99968442011-11-29 18:15:50 +0000564template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000565template <class _Arg>
566void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000567#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000568__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000569#else
Howard Hinnant99968442011-11-29 18:15:50 +0000570__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000571#endif
572{
573 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000574#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000575 if (this->__has_value())
576 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000577#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000578 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000579 this->__state_ |= base::__constructed | base::ready;
580 __lk.unlock();
581 __cv_.notify_all();
582}
583
Howard Hinnant99968442011-11-29 18:15:50 +0000584template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000585template <class _Arg>
586void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000587#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000588__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000589#else
Howard Hinnant99968442011-11-29 18:15:50 +0000590__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000591#endif
592{
593 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000594#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000595 if (this->__has_value())
596 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000597#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000598 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000599 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000600 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000601 __lk.unlock();
602}
603
Howard Hinnant99968442011-11-29 18:15:50 +0000604template <class _Rp>
605_Rp
606__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000607{
608 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000609 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000610 if (this->__exception_ != nullptr)
611 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000612 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000613}
614
Howard Hinnant99968442011-11-29 18:15:50 +0000615template <class _Rp>
616typename add_lvalue_reference<_Rp>::type
617__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000618{
619 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000620 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000621 if (this->__exception_ != nullptr)
622 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000623 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000624}
625
Howard Hinnant99968442011-11-29 18:15:50 +0000626template <class _Rp>
627class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000628 : public __assoc_sub_state
629{
630 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000631 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000632protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000633 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000634
Howard Hinnant1694d232011-05-28 14:41:13 +0000635 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000636public:
637
Howard Hinnant99968442011-11-29 18:15:50 +0000638 void set_value(_Rp& __arg);
639 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000640
Howard Hinnant99968442011-11-29 18:15:50 +0000641 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000642};
643
Howard Hinnant99968442011-11-29 18:15:50 +0000644template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000645void
Howard Hinnant99968442011-11-29 18:15:50 +0000646__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000647{
648 delete this;
649}
650
Howard Hinnant99968442011-11-29 18:15:50 +0000651template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000652void
Howard Hinnant99968442011-11-29 18:15:50 +0000653__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000654{
655 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000656#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000657 if (this->__has_value())
658 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000659#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000660 __value_ = &__arg;
661 this->__state_ |= base::__constructed | base::ready;
662 __lk.unlock();
663 __cv_.notify_all();
664}
665
Howard Hinnant99968442011-11-29 18:15:50 +0000666template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000667void
Howard Hinnant99968442011-11-29 18:15:50 +0000668__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000669{
670 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000671#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000672 if (this->__has_value())
673 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000674#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000675 __value_ = &__arg;
676 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000677 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000678 __lk.unlock();
679}
680
Howard Hinnant99968442011-11-29 18:15:50 +0000681template <class _Rp>
682_Rp&
683__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000684{
685 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000686 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000687 if (this->__exception_ != nullptr)
688 rethrow_exception(this->__exception_);
689 return *__value_;
690}
691
Howard Hinnant99968442011-11-29 18:15:50 +0000692template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000693class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000694 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000695{
Howard Hinnant99968442011-11-29 18:15:50 +0000696 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000697 _Alloc __alloc_;
698
Howard Hinnant1694d232011-05-28 14:41:13 +0000699 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000700public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000702 explicit __assoc_state_alloc(const _Alloc& __a)
703 : __alloc_(__a) {}
704};
705
Howard Hinnant99968442011-11-29 18:15:50 +0000706template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000707void
Howard Hinnant99968442011-11-29 18:15:50 +0000708__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000709{
710 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000711 reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000712 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
713 this->~__assoc_state_alloc();
714 __a.deallocate(this, 1);
715}
716
Howard Hinnant99968442011-11-29 18:15:50 +0000717template <class _Rp, class _Alloc>
718class __assoc_state_alloc<_Rp&, _Alloc>
719 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000720{
Howard Hinnant99968442011-11-29 18:15:50 +0000721 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000722 _Alloc __alloc_;
723
Howard Hinnant1694d232011-05-28 14:41:13 +0000724 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000725public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000727 explicit __assoc_state_alloc(const _Alloc& __a)
728 : __alloc_(__a) {}
729};
730
Howard Hinnant99968442011-11-29 18:15:50 +0000731template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000732void
Howard Hinnant99968442011-11-29 18:15:50 +0000733__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000734{
735 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
736 this->~__assoc_state_alloc();
737 __a.deallocate(this, 1);
738}
739
Howard Hinnant47499b12010-08-27 20:10:19 +0000740template <class _Alloc>
741class __assoc_sub_state_alloc
742 : public __assoc_sub_state
743{
744 typedef __assoc_sub_state base;
745 _Alloc __alloc_;
746
Howard Hinnant1694d232011-05-28 14:41:13 +0000747 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000748public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000749 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000750 explicit __assoc_sub_state_alloc(const _Alloc& __a)
751 : __alloc_(__a) {}
752};
753
754template <class _Alloc>
755void
Howard Hinnant1694d232011-05-28 14:41:13 +0000756__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000757{
Howard Hinnantf39daa82010-08-28 21:01:06 +0000758 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000759 this->~__assoc_sub_state_alloc();
760 __a.deallocate(this, 1);
761}
762
Howard Hinnant99968442011-11-29 18:15:50 +0000763template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000764class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000765 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000766{
Howard Hinnant99968442011-11-29 18:15:50 +0000767 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000768
Howard Hinnant99968442011-11-29 18:15:50 +0000769 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000770
771public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000772#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000773 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000774#endif
775
776 virtual void __execute();
777};
778
Howard Hinnant73d21a42010-09-04 23:28:19 +0000779#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000780
Howard Hinnant99968442011-11-29 18:15:50 +0000781template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000782inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000783__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
784 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000785{
786 this->__set_deferred();
787}
788
Howard Hinnant73d21a42010-09-04 23:28:19 +0000789#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000790
Howard Hinnant99968442011-11-29 18:15:50 +0000791template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000792void
Howard Hinnant99968442011-11-29 18:15:50 +0000793__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000794{
795#ifndef _LIBCPP_NO_EXCEPTIONS
796 try
797 {
798#endif // _LIBCPP_NO_EXCEPTIONS
799 this->set_value(__func_());
800#ifndef _LIBCPP_NO_EXCEPTIONS
801 }
802 catch (...)
803 {
804 this->set_exception(current_exception());
805 }
806#endif // _LIBCPP_NO_EXCEPTIONS
807}
808
Howard Hinnant99968442011-11-29 18:15:50 +0000809template <class _Fp>
810class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000811 : public __assoc_sub_state
812{
813 typedef __assoc_sub_state base;
814
Howard Hinnant99968442011-11-29 18:15:50 +0000815 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000816
817public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000818#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000819 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000820#endif
821
822 virtual void __execute();
823};
824
Howard Hinnant73d21a42010-09-04 23:28:19 +0000825#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000826
Howard Hinnant99968442011-11-29 18:15:50 +0000827template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000828inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000829__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
830 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000831{
832 this->__set_deferred();
833}
834
Howard Hinnant73d21a42010-09-04 23:28:19 +0000835#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000836
Howard Hinnant99968442011-11-29 18:15:50 +0000837template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000838void
Howard Hinnant99968442011-11-29 18:15:50 +0000839__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000840{
841#ifndef _LIBCPP_NO_EXCEPTIONS
842 try
843 {
844#endif // _LIBCPP_NO_EXCEPTIONS
845 __func_();
846 this->set_value();
847#ifndef _LIBCPP_NO_EXCEPTIONS
848 }
849 catch (...)
850 {
851 this->set_exception(current_exception());
852 }
853#endif // _LIBCPP_NO_EXCEPTIONS
854}
855
Howard Hinnant99968442011-11-29 18:15:50 +0000856template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000857class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000858 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000859{
Howard Hinnant99968442011-11-29 18:15:50 +0000860 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000861
Howard Hinnant99968442011-11-29 18:15:50 +0000862 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000863
Howard Hinnant1694d232011-05-28 14:41:13 +0000864 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000865public:
866#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000867 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000868#endif
869
870 virtual void __execute();
871};
872
873#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
874
Howard Hinnant99968442011-11-29 18:15:50 +0000875template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000876inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000877__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
878 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000879{
880}
881
882#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
883
Howard Hinnant99968442011-11-29 18:15:50 +0000884template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000885void
Howard Hinnant99968442011-11-29 18:15:50 +0000886__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000887{
888#ifndef _LIBCPP_NO_EXCEPTIONS
889 try
890 {
891#endif // _LIBCPP_NO_EXCEPTIONS
892 this->set_value(__func_());
893#ifndef _LIBCPP_NO_EXCEPTIONS
894 }
895 catch (...)
896 {
897 this->set_exception(current_exception());
898 }
899#endif // _LIBCPP_NO_EXCEPTIONS
900}
901
Howard Hinnant99968442011-11-29 18:15:50 +0000902template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000903void
Howard Hinnant99968442011-11-29 18:15:50 +0000904__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000905{
906 this->wait();
907 base::__on_zero_shared();
908}
909
Howard Hinnant99968442011-11-29 18:15:50 +0000910template <class _Fp>
911class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000912 : public __assoc_sub_state
913{
914 typedef __assoc_sub_state base;
915
Howard Hinnant99968442011-11-29 18:15:50 +0000916 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000917
Howard Hinnant1694d232011-05-28 14:41:13 +0000918 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000919public:
920#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000921 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000922#endif
923
924 virtual void __execute();
925};
926
927#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
928
Howard Hinnant99968442011-11-29 18:15:50 +0000929template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000930inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000931__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
932 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000933{
934}
935
936#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
937
Howard Hinnant99968442011-11-29 18:15:50 +0000938template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000939void
Howard Hinnant99968442011-11-29 18:15:50 +0000940__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000941{
942#ifndef _LIBCPP_NO_EXCEPTIONS
943 try
944 {
945#endif // _LIBCPP_NO_EXCEPTIONS
946 __func_();
947 this->set_value();
948#ifndef _LIBCPP_NO_EXCEPTIONS
949 }
950 catch (...)
951 {
952 this->set_exception(current_exception());
953 }
954#endif // _LIBCPP_NO_EXCEPTIONS
955}
956
Howard Hinnant99968442011-11-29 18:15:50 +0000957template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000958void
Howard Hinnant99968442011-11-29 18:15:50 +0000959__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000960{
961 this->wait();
962 base::__on_zero_shared();
963}
964
Howard Hinnant33be35e2012-09-14 00:39:16 +0000965template <class _Rp> class _LIBCPP_VISIBLE promise;
966template <class _Rp> class _LIBCPP_VISIBLE shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +0000967
968// future
969
Howard Hinnant33be35e2012-09-14 00:39:16 +0000970template <class _Rp> class _LIBCPP_VISIBLE future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000971
Howard Hinnant99968442011-11-29 18:15:50 +0000972template <class _Rp, class _Fp>
973future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000974#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000975__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000976#else
Howard Hinnant99968442011-11-29 18:15:50 +0000977__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000978#endif
979
Howard Hinnant99968442011-11-29 18:15:50 +0000980template <class _Rp, class _Fp>
981future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000982#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000983__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000984#else
Howard Hinnant99968442011-11-29 18:15:50 +0000985__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000986#endif
987
Howard Hinnant99968442011-11-29 18:15:50 +0000988template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000989class _LIBCPP_VISIBLE future
Howard Hinnant47499b12010-08-27 20:10:19 +0000990{
Howard Hinnant99968442011-11-29 18:15:50 +0000991 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000992
Howard Hinnant99968442011-11-29 18:15:50 +0000993 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +0000994
995 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +0000996 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000997
Howard Hinnant73d21a42010-09-04 23:28:19 +0000998#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000999 template <class _R1, class _Fp>
1000 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1001 template <class _R1, class _Fp>
1002 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001003#else
Howard Hinnant99968442011-11-29 18:15:50 +00001004 template <class _R1, class _Fp>
1005 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1006 template <class _R1, class _Fp>
1007 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001008#endif
1009
Howard Hinnant47499b12010-08-27 20:10:19 +00001010public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001012 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001013#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001015 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001016 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1017 future(const future&) = delete;
1018 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001019 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001020 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001021 {
1022 future(std::move(__rhs)).swap(*this);
1023 return *this;
1024 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001025#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001026private:
1027 future(const future&);
1028 future& operator=(const future&);
1029public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001030#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001031 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001032 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001033
1034 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001035 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001036
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001037 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001038 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001039
1040 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001041 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001042 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001043
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001045 void wait() const {__state_->wait();}
1046 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001048 future_status
1049 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1050 {return __state_->wait_for(__rel_time);}
1051 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001052 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001053 future_status
1054 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1055 {return __state_->wait_until(__abs_time);}
1056};
1057
Howard Hinnant99968442011-11-29 18:15:50 +00001058template <class _Rp>
1059future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001060 : __state_(__state)
1061{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001062#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001063 if (__state_->__has_future_attached())
1064 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001065#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001066 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001067 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001068}
1069
Howard Hinnant54da3382010-08-30 18:46:21 +00001070struct __release_shared_count
1071{
1072 void operator()(__shared_count* p) {p->__release_shared();}
1073};
1074
Howard Hinnant99968442011-11-29 18:15:50 +00001075template <class _Rp>
1076future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001077{
1078 if (__state_)
1079 __state_->__release_shared();
1080}
1081
Howard Hinnant99968442011-11-29 18:15:50 +00001082template <class _Rp>
1083_Rp
1084future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001085{
Howard Hinnant54da3382010-08-30 18:46:21 +00001086 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001087 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001088 __state_ = nullptr;
1089 return __s->move();
1090}
1091
Howard Hinnant99968442011-11-29 18:15:50 +00001092template <class _Rp>
1093class _LIBCPP_VISIBLE future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001094{
Howard Hinnant99968442011-11-29 18:15:50 +00001095 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001096
Howard Hinnant99968442011-11-29 18:15:50 +00001097 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001098
1099 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001100 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001101
Howard Hinnant73d21a42010-09-04 23:28:19 +00001102#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001103 template <class _R1, class _Fp>
1104 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1105 template <class _R1, class _Fp>
1106 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001107#else
Howard Hinnant99968442011-11-29 18:15:50 +00001108 template <class _R1, class _Fp>
1109 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1110 template <class _R1, class _Fp>
1111 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001112#endif
1113
Howard Hinnant47499b12010-08-27 20:10:19 +00001114public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001115 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001116 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001117#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001118 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001119 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001120 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1121 future(const future&) = delete;
1122 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001123 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001124 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001125 {
1126 future(std::move(__rhs)).swap(*this);
1127 return *this;
1128 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001129#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001130private:
1131 future(const future&);
1132 future& operator=(const future&);
1133public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001134#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001135 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001136 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001137
1138 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001139 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001140
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001142 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001143
1144 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001145 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001146 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001147
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001148 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001149 void wait() const {__state_->wait();}
1150 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001151 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001152 future_status
1153 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1154 {return __state_->wait_for(__rel_time);}
1155 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001156 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001157 future_status
1158 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1159 {return __state_->wait_until(__abs_time);}
1160};
1161
Howard Hinnant99968442011-11-29 18:15:50 +00001162template <class _Rp>
1163future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001164 : __state_(__state)
1165{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001166#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001167 if (__state_->__has_future_attached())
1168 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001169#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001170 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001171 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001172}
1173
Howard Hinnant99968442011-11-29 18:15:50 +00001174template <class _Rp>
1175future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001176{
1177 if (__state_)
1178 __state_->__release_shared();
1179}
1180
Howard Hinnant99968442011-11-29 18:15:50 +00001181template <class _Rp>
1182_Rp&
1183future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001184{
Howard Hinnant54da3382010-08-30 18:46:21 +00001185 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001186 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001187 __state_ = nullptr;
1188 return __s->copy();
1189}
1190
1191template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001192class _LIBCPP_VISIBLE future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001193{
1194 __assoc_sub_state* __state_;
1195
1196 explicit future(__assoc_sub_state* __state);
1197
1198 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001199 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001200
Howard Hinnant73d21a42010-09-04 23:28:19 +00001201#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001202 template <class _R1, class _Fp>
1203 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1204 template <class _R1, class _Fp>
1205 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001206#else
Howard Hinnant99968442011-11-29 18:15:50 +00001207 template <class _R1, class _Fp>
1208 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1209 template <class _R1, class _Fp>
1210 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001211#endif
1212
Howard Hinnant47499b12010-08-27 20:10:19 +00001213public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001214 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001215 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001216#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001217 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001218 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001219 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1220 future(const future&) = delete;
1221 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001222 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001223 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001224 {
1225 future(std::move(__rhs)).swap(*this);
1226 return *this;
1227 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001228#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001229private:
1230 future(const future&);
1231 future& operator=(const future&);
1232public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001233#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001234 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001235 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001236
1237 // retrieving the value
1238 void get();
1239
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001241 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001242
1243 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001245 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001246
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001248 void wait() const {__state_->wait();}
1249 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001250 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001251 future_status
1252 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1253 {return __state_->wait_for(__rel_time);}
1254 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001255 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001256 future_status
1257 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1258 {return __state_->wait_until(__abs_time);}
1259};
1260
Howard Hinnant99968442011-11-29 18:15:50 +00001261template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001262inline _LIBCPP_INLINE_VISIBILITY
1263void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001264swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00001265{
1266 __x.swap(__y);
1267}
1268
Howard Hinnant47499b12010-08-27 20:10:19 +00001269// promise<R>
1270
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001271template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001272
Howard Hinnant99968442011-11-29 18:15:50 +00001273template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001274class _LIBCPP_VISIBLE promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001275{
Howard Hinnant99968442011-11-29 18:15:50 +00001276 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001277
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001278 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001279 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001280
1281 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001282public:
1283 promise();
1284 template <class _Alloc>
1285 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001286#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001287 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001288 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001289 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1290 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001291#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001292private:
1293 promise(const promise& __rhs);
1294public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001295#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001296 ~promise();
1297
1298 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001299#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001301 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001302 {
1303 promise(std::move(__rhs)).swap(*this);
1304 return *this;
1305 }
1306 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001307#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001308private:
1309 promise& operator=(const promise& __rhs);
1310public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001311#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001312 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001313 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001314
1315 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001316 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001317
1318 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001319 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001320#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001321 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001322#endif
1323 void set_exception(exception_ptr __p);
1324
1325 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001326 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001327#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001328 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001329#endif
1330 void set_exception_at_thread_exit(exception_ptr __p);
1331};
1332
Howard Hinnant99968442011-11-29 18:15:50 +00001333template <class _Rp>
1334promise<_Rp>::promise()
1335 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001336{
1337}
1338
Howard Hinnant99968442011-11-29 18:15:50 +00001339template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001340template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001341promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001342{
Howard Hinnant99968442011-11-29 18:15:50 +00001343 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001344 typedef __allocator_destructor<_A2> _D2;
1345 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001346 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1347 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001348 __state_ = __hold.release();
1349}
1350
Howard Hinnant99968442011-11-29 18:15:50 +00001351template <class _Rp>
1352promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001353{
1354 if (__state_)
1355 {
1356 if (!__state_->__has_value() && __state_->use_count() > 1)
1357 __state_->set_exception(make_exception_ptr(
1358 future_error(make_error_code(future_errc::broken_promise))
1359 ));
1360 __state_->__release_shared();
1361 }
1362}
1363
Howard Hinnant99968442011-11-29 18:15:50 +00001364template <class _Rp>
1365future<_Rp>
1366promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001367{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001368#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001369 if (__state_ == nullptr)
1370 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001371#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001372 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001373}
1374
Howard Hinnant99968442011-11-29 18:15:50 +00001375template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001376void
Howard Hinnant99968442011-11-29 18:15:50 +00001377promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001378{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001379#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001380 if (__state_ == nullptr)
1381 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001382#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001383 __state_->set_value(__r);
1384}
1385
Howard Hinnant73d21a42010-09-04 23:28:19 +00001386#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001387
Howard Hinnant99968442011-11-29 18:15:50 +00001388template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001389void
Howard Hinnant99968442011-11-29 18:15:50 +00001390promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001391{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001392#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001393 if (__state_ == nullptr)
1394 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001395#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001396 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001397}
1398
Howard Hinnant73d21a42010-09-04 23:28:19 +00001399#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001400
Howard Hinnant99968442011-11-29 18:15:50 +00001401template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001402void
Howard Hinnant99968442011-11-29 18:15:50 +00001403promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001404{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001405#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001406 if (__state_ == nullptr)
1407 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001408#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001409 __state_->set_exception(__p);
1410}
1411
Howard Hinnant99968442011-11-29 18:15:50 +00001412template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001413void
Howard Hinnant99968442011-11-29 18:15:50 +00001414promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001415{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001416#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001417 if (__state_ == nullptr)
1418 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001419#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001420 __state_->set_value_at_thread_exit(__r);
1421}
1422
Howard Hinnant73d21a42010-09-04 23:28:19 +00001423#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001424
Howard Hinnant99968442011-11-29 18:15:50 +00001425template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001426void
Howard Hinnant99968442011-11-29 18:15:50 +00001427promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001428{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001429#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001430 if (__state_ == nullptr)
1431 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001432#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001433 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001434}
1435
Howard Hinnant73d21a42010-09-04 23:28:19 +00001436#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001437
Howard Hinnant99968442011-11-29 18:15:50 +00001438template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001439void
Howard Hinnant99968442011-11-29 18:15:50 +00001440promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001441{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001442#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001443 if (__state_ == nullptr)
1444 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001445#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001446 __state_->set_exception_at_thread_exit(__p);
1447}
1448
1449// promise<R&>
1450
Howard Hinnant99968442011-11-29 18:15:50 +00001451template <class _Rp>
1452class _LIBCPP_VISIBLE promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001453{
Howard Hinnant99968442011-11-29 18:15:50 +00001454 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001455
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001456 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001457 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001458
1459 template <class> friend class packaged_task;
1460
Howard Hinnant47499b12010-08-27 20:10:19 +00001461public:
1462 promise();
1463 template <class _Allocator>
1464 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001465#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001467 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001468 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1469 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001470#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001471private:
1472 promise(const promise& __rhs);
1473public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001474#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001475 ~promise();
1476
1477 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001478#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001479 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001480 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001481 {
1482 promise(std::move(__rhs)).swap(*this);
1483 return *this;
1484 }
1485 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001486#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001487private:
1488 promise& operator=(const promise& __rhs);
1489public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001490#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001491 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001492 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001493
1494 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001495 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001496
1497 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001498 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001499 void set_exception(exception_ptr __p);
1500
1501 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001502 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001503 void set_exception_at_thread_exit(exception_ptr __p);
1504};
1505
Howard Hinnant99968442011-11-29 18:15:50 +00001506template <class _Rp>
1507promise<_Rp&>::promise()
1508 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001509{
1510}
1511
Howard Hinnant99968442011-11-29 18:15:50 +00001512template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001513template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001514promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001515{
Howard Hinnant99968442011-11-29 18:15:50 +00001516 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001517 typedef __allocator_destructor<_A2> _D2;
1518 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001519 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1520 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001521 __state_ = __hold.release();
1522}
1523
Howard Hinnant99968442011-11-29 18:15:50 +00001524template <class _Rp>
1525promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001526{
1527 if (__state_)
1528 {
1529 if (!__state_->__has_value() && __state_->use_count() > 1)
1530 __state_->set_exception(make_exception_ptr(
1531 future_error(make_error_code(future_errc::broken_promise))
1532 ));
1533 __state_->__release_shared();
1534 }
1535}
1536
Howard Hinnant99968442011-11-29 18:15:50 +00001537template <class _Rp>
1538future<_Rp&>
1539promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001540{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001541#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001542 if (__state_ == nullptr)
1543 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001544#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001545 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001546}
1547
Howard Hinnant99968442011-11-29 18:15:50 +00001548template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001549void
Howard Hinnant99968442011-11-29 18:15:50 +00001550promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001551{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001552#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001553 if (__state_ == nullptr)
1554 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001555#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001556 __state_->set_value(__r);
1557}
1558
Howard Hinnant99968442011-11-29 18:15:50 +00001559template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001560void
Howard Hinnant99968442011-11-29 18:15:50 +00001561promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001562{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001563#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001564 if (__state_ == nullptr)
1565 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001566#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001567 __state_->set_exception(__p);
1568}
1569
Howard Hinnant99968442011-11-29 18:15:50 +00001570template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001571void
Howard Hinnant99968442011-11-29 18:15:50 +00001572promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001573{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001574#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001575 if (__state_ == nullptr)
1576 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001577#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001578 __state_->set_value_at_thread_exit(__r);
1579}
1580
Howard Hinnant99968442011-11-29 18:15:50 +00001581template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001582void
Howard Hinnant99968442011-11-29 18:15:50 +00001583promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001584{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001585#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001586 if (__state_ == nullptr)
1587 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001588#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001589 __state_->set_exception_at_thread_exit(__p);
1590}
1591
1592// promise<void>
1593
1594template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001595class _LIBCPP_VISIBLE promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001596{
1597 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001598
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001599 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001600 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001601
1602 template <class> friend class packaged_task;
1603
Howard Hinnant47499b12010-08-27 20:10:19 +00001604public:
1605 promise();
1606 template <class _Allocator>
1607 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001608#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001609 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001610 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001611 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1612 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001613#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001614private:
1615 promise(const promise& __rhs);
1616public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001617#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001618 ~promise();
1619
1620 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001621#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001623 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001624 {
1625 promise(std::move(__rhs)).swap(*this);
1626 return *this;
1627 }
1628 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001629#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001630private:
1631 promise& operator=(const promise& __rhs);
1632public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001633#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001634 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001635 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001636
1637 // retrieving the result
1638 future<void> get_future();
1639
1640 // setting the result
1641 void set_value();
1642 void set_exception(exception_ptr __p);
1643
1644 // setting the result with deferred notification
1645 void set_value_at_thread_exit();
1646 void set_exception_at_thread_exit(exception_ptr __p);
1647};
1648
1649template <class _Alloc>
1650promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1651{
1652 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1653 typedef __allocator_destructor<_A2> _D2;
1654 _A2 __a(__a0);
1655 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1656 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1657 __state_ = __hold.release();
1658}
1659
Howard Hinnant99968442011-11-29 18:15:50 +00001660template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001661inline _LIBCPP_INLINE_VISIBILITY
1662void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001663swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001664{
1665 __x.swap(__y);
1666}
1667
Howard Hinnant99968442011-11-29 18:15:50 +00001668template <class _Rp, class _Alloc>
1669 struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001670 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001671
Howard Hinnant54da3382010-08-30 18:46:21 +00001672#ifndef _LIBCPP_HAS_NO_VARIADICS
1673
1674// packaged_task
1675
1676template<class _Fp> class __packaged_task_base;
1677
Howard Hinnant99968442011-11-29 18:15:50 +00001678template<class _Rp, class ..._ArgTypes>
1679class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001680{
1681 __packaged_task_base(const __packaged_task_base&);
1682 __packaged_task_base& operator=(const __packaged_task_base&);
1683public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001684 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001685 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001686 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001687 virtual ~__packaged_task_base() {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001688 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001689 virtual void destroy() = 0;
1690 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001691 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001692};
1693
1694template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1695
Howard Hinnant99968442011-11-29 18:15:50 +00001696template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1697class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1698 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001699{
Howard Hinnant99968442011-11-29 18:15:50 +00001700 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001701public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001702 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001703 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001705 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001707 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001708 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001709 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001710 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001711 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001712 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001713 virtual void destroy();
1714 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001715 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001716};
1717
Howard Hinnant99968442011-11-29 18:15:50 +00001718template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001719void
Howard Hinnant99968442011-11-29 18:15:50 +00001720__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001721 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001722{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001723 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001724}
1725
Howard Hinnant99968442011-11-29 18:15:50 +00001726template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001727void
Howard Hinnant99968442011-11-29 18:15:50 +00001728__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001729{
Howard Hinnant99968442011-11-29 18:15:50 +00001730 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001731}
1732
Howard Hinnant99968442011-11-29 18:15:50 +00001733template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001734void
Howard Hinnant99968442011-11-29 18:15:50 +00001735__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001736{
Howard Hinnant99968442011-11-29 18:15:50 +00001737 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1738 _Ap __a(__f_.second());
1739 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001740 __a.deallocate(this, 1);
1741}
1742
Howard Hinnant99968442011-11-29 18:15:50 +00001743template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1744_Rp
1745__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001746{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001747 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001748}
1749
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001750template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001751
Howard Hinnant99968442011-11-29 18:15:50 +00001752template<class _Rp, class ..._ArgTypes>
1753class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001754{
Howard Hinnant99968442011-11-29 18:15:50 +00001755 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant54da3382010-08-30 18:46:21 +00001756 aligned_storage<3*sizeof(void*)>::type __buf_;
1757 __base* __f_;
1758
1759public:
Howard Hinnant99968442011-11-29 18:15:50 +00001760 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001761
1762 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001763 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001764 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001765 template<class _Fp>
1766 __packaged_task_function(_Fp&& __f);
1767 template<class _Fp, class _Alloc>
1768 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001769
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001770 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1771 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001772
1773 __packaged_task_function(const __packaged_task_function&) = delete;
1774 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1775
1776 ~__packaged_task_function();
1777
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001778 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001779
Howard Hinnant99968442011-11-29 18:15:50 +00001780 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001781};
1782
Howard Hinnant99968442011-11-29 18:15:50 +00001783template<class _Rp, class ..._ArgTypes>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001784__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001785{
1786 if (__f.__f_ == nullptr)
1787 __f_ = nullptr;
1788 else if (__f.__f_ == (__base*)&__f.__buf_)
1789 {
1790 __f_ = (__base*)&__buf_;
1791 __f.__f_->__move_to(__f_);
1792 }
1793 else
1794 {
1795 __f_ = __f.__f_;
1796 __f.__f_ = nullptr;
1797 }
1798}
1799
Howard Hinnant99968442011-11-29 18:15:50 +00001800template<class _Rp, class ..._ArgTypes>
1801template <class _Fp>
1802__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001803 : __f_(nullptr)
1804{
Howard Hinnant99968442011-11-29 18:15:50 +00001805 typedef typename remove_reference<_Fp>::type _FR;
1806 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001807 if (sizeof(_FF) <= sizeof(__buf_))
1808 {
1809 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001810 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001811 }
1812 else
1813 {
Howard Hinnant99968442011-11-29 18:15:50 +00001814 typedef allocator<_FF> _Ap;
1815 _Ap __a;
1816 typedef __allocator_destructor<_Ap> _Dp;
1817 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1818 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001819 __f_ = __hold.release();
1820 }
1821}
1822
Howard Hinnant99968442011-11-29 18:15:50 +00001823template<class _Rp, class ..._ArgTypes>
1824template <class _Fp, class _Alloc>
1825__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1826 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001827 : __f_(nullptr)
1828{
1829 typedef allocator_traits<_Alloc> __alloc_traits;
Howard Hinnant99968442011-11-29 18:15:50 +00001830 typedef typename remove_reference<_Fp>::type _FR;
1831 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001832 if (sizeof(_FF) <= sizeof(__buf_))
1833 {
1834 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001835 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001836 }
1837 else
1838 {
1839 typedef typename __alloc_traits::template
1840#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1841 rebind_alloc<_FF>
1842#else
1843 rebind_alloc<_FF>::other
1844#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001845 _Ap;
1846 _Ap __a(__a0);
1847 typedef __allocator_destructor<_Ap> _Dp;
1848 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1849 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001850 __f_ = __hold.release();
1851 }
1852}
1853
Howard Hinnant99968442011-11-29 18:15:50 +00001854template<class _Rp, class ..._ArgTypes>
1855__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001856__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001857{
1858 if (__f_ == (__base*)&__buf_)
1859 __f_->destroy();
1860 else if (__f_)
1861 __f_->destroy_deallocate();
1862 __f_ = nullptr;
1863 if (__f.__f_ == nullptr)
1864 __f_ = nullptr;
1865 else if (__f.__f_ == (__base*)&__f.__buf_)
1866 {
1867 __f_ = (__base*)&__buf_;
1868 __f.__f_->__move_to(__f_);
1869 }
1870 else
1871 {
1872 __f_ = __f.__f_;
1873 __f.__f_ = nullptr;
1874 }
Argyrios Kyrtzidis1dc6f7a2012-10-13 02:03:45 +00001875 return *this;
Howard Hinnant54da3382010-08-30 18:46:21 +00001876}
1877
Howard Hinnant99968442011-11-29 18:15:50 +00001878template<class _Rp, class ..._ArgTypes>
1879__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001880{
1881 if (__f_ == (__base*)&__buf_)
1882 __f_->destroy();
1883 else if (__f_)
1884 __f_->destroy_deallocate();
1885}
1886
Howard Hinnant99968442011-11-29 18:15:50 +00001887template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001888void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001889__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001890{
1891 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1892 {
1893 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1894 __base* __t = (__base*)&__tempbuf;
1895 __f_->__move_to(__t);
1896 __f_->destroy();
1897 __f_ = nullptr;
1898 __f.__f_->__move_to((__base*)&__buf_);
1899 __f.__f_->destroy();
1900 __f.__f_ = nullptr;
1901 __f_ = (__base*)&__buf_;
1902 __t->__move_to((__base*)&__f.__buf_);
1903 __t->destroy();
1904 __f.__f_ = (__base*)&__f.__buf_;
1905 }
1906 else if (__f_ == (__base*)&__buf_)
1907 {
1908 __f_->__move_to((__base*)&__f.__buf_);
1909 __f_->destroy();
1910 __f_ = __f.__f_;
1911 __f.__f_ = (__base*)&__f.__buf_;
1912 }
1913 else if (__f.__f_ == (__base*)&__f.__buf_)
1914 {
1915 __f.__f_->__move_to((__base*)&__buf_);
1916 __f.__f_->destroy();
1917 __f.__f_ = __f_;
1918 __f_ = (__base*)&__buf_;
1919 }
1920 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001921 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001922}
1923
Howard Hinnant99968442011-11-29 18:15:50 +00001924template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001925inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001926_Rp
1927__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00001928{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001929 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001930}
1931
Howard Hinnant99968442011-11-29 18:15:50 +00001932template<class _Rp, class ..._ArgTypes>
1933class _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001934{
1935public:
Howard Hinnant99968442011-11-29 18:15:50 +00001936 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001937
1938private:
1939 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1940 promise<result_type> __p_;
1941
1942public:
1943 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001944 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001945 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001946 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001947 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001948 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
1949 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001950 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001951 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1952 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00001953 __p_(allocator_arg, __a) {}
1954 // ~packaged_task() = default;
1955
1956 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00001957 packaged_task(const packaged_task&) = delete;
1958 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00001959
1960 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001961 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001962 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00001963 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001964 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001965 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001966 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001967 __f_ = _VSTD::move(__other.__f_);
1968 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001969 return *this;
1970 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001971 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001972 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001973 {
1974 __f_.swap(__other.__f_);
1975 __p_.swap(__other.__p_);
1976 }
1977
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001978 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001979 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00001980
1981 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001982 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001983 future<result_type> get_future() {return __p_.get_future();}
1984
1985 // execution
1986 void operator()(_ArgTypes... __args);
1987 void make_ready_at_thread_exit(_ArgTypes... __args);
1988
1989 void reset();
1990};
1991
Howard Hinnant99968442011-11-29 18:15:50 +00001992template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001993void
Howard Hinnant99968442011-11-29 18:15:50 +00001994packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00001995{
1996#ifndef _LIBCPP_NO_EXCEPTIONS
1997 if (__p_.__state_ == nullptr)
1998 throw future_error(make_error_code(future_errc::no_state));
1999 if (__p_.__state_->__has_value())
2000 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2001 try
2002 {
2003#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002004 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002005#ifndef _LIBCPP_NO_EXCEPTIONS
2006 }
2007 catch (...)
2008 {
2009 __p_.set_exception(current_exception());
2010 }
2011#endif // _LIBCPP_NO_EXCEPTIONS
2012}
2013
Howard Hinnant99968442011-11-29 18:15:50 +00002014template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002015void
Howard Hinnant99968442011-11-29 18:15:50 +00002016packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002017{
2018#ifndef _LIBCPP_NO_EXCEPTIONS
2019 if (__p_.__state_ == nullptr)
2020 throw future_error(make_error_code(future_errc::no_state));
2021 if (__p_.__state_->__has_value())
2022 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2023 try
2024 {
2025#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002026 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002027#ifndef _LIBCPP_NO_EXCEPTIONS
2028 }
2029 catch (...)
2030 {
2031 __p_.set_exception_at_thread_exit(current_exception());
2032 }
2033#endif // _LIBCPP_NO_EXCEPTIONS
2034}
2035
Howard Hinnant99968442011-11-29 18:15:50 +00002036template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002037void
Howard Hinnant99968442011-11-29 18:15:50 +00002038packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002039{
2040#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002041 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002042 throw future_error(make_error_code(future_errc::no_state));
2043#endif // _LIBCPP_NO_EXCEPTIONS
2044 __p_ = promise<result_type>();
2045}
2046
2047template<class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002048class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002049{
2050public:
2051 typedef void result_type;
2052
2053private:
2054 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2055 promise<result_type> __p_;
2056
2057public:
2058 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002060 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00002061 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002063 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2064 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002065 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002066 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2067 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002068 __p_(allocator_arg, __a) {}
2069 // ~packaged_task() = default;
2070
2071 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002072 packaged_task(const packaged_task&) = delete;
2073 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002074
2075 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002077 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002078 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002079 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002080 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002081 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002082 __f_ = _VSTD::move(__other.__f_);
2083 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002084 return *this;
2085 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002086 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002087 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002088 {
2089 __f_.swap(__other.__f_);
2090 __p_.swap(__other.__p_);
2091 }
2092
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002093 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002094 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002095
2096 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002098 future<result_type> get_future() {return __p_.get_future();}
2099
2100 // execution
2101 void operator()(_ArgTypes... __args);
2102 void make_ready_at_thread_exit(_ArgTypes... __args);
2103
2104 void reset();
2105};
2106
2107template<class ..._ArgTypes>
2108void
2109packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2110{
2111#ifndef _LIBCPP_NO_EXCEPTIONS
2112 if (__p_.__state_ == nullptr)
2113 throw future_error(make_error_code(future_errc::no_state));
2114 if (__p_.__state_->__has_value())
2115 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2116 try
2117 {
2118#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002119 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002120 __p_.set_value();
2121#ifndef _LIBCPP_NO_EXCEPTIONS
2122 }
2123 catch (...)
2124 {
2125 __p_.set_exception(current_exception());
2126 }
2127#endif // _LIBCPP_NO_EXCEPTIONS
2128}
2129
2130template<class ..._ArgTypes>
2131void
2132packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2133{
2134#ifndef _LIBCPP_NO_EXCEPTIONS
2135 if (__p_.__state_ == nullptr)
2136 throw future_error(make_error_code(future_errc::no_state));
2137 if (__p_.__state_->__has_value())
2138 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2139 try
2140 {
2141#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002142 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002143 __p_.set_value_at_thread_exit();
2144#ifndef _LIBCPP_NO_EXCEPTIONS
2145 }
2146 catch (...)
2147 {
2148 __p_.set_exception_at_thread_exit(current_exception());
2149 }
2150#endif // _LIBCPP_NO_EXCEPTIONS
2151}
2152
2153template<class ..._ArgTypes>
2154void
2155packaged_task<void(_ArgTypes...)>::reset()
2156{
2157#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002158 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002159 throw future_error(make_error_code(future_errc::no_state));
2160#endif // _LIBCPP_NO_EXCEPTIONS
2161 __p_ = promise<result_type>();
2162}
2163
2164template <class _Callable>
2165inline _LIBCPP_INLINE_VISIBILITY
2166void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002167swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002168{
2169 __x.swap(__y);
2170}
2171
2172template <class _Callable, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002173struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2174 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002175
Howard Hinnant99968442011-11-29 18:15:50 +00002176template <class _Rp, class _Fp>
2177future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002178#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002179__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002180#else
Howard Hinnant99968442011-11-29 18:15:50 +00002181__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002182#endif
2183{
Howard Hinnant99968442011-11-29 18:15:50 +00002184 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2185 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2186 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002187}
2188
Howard Hinnant99968442011-11-29 18:15:50 +00002189template <class _Rp, class _Fp>
2190future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002191#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002192__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002193#else
Howard Hinnant99968442011-11-29 18:15:50 +00002194__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002195#endif
2196{
Howard Hinnant99968442011-11-29 18:15:50 +00002197 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2198 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2199 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2200 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002201}
2202
Howard Hinnant99968442011-11-29 18:15:50 +00002203template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002204class __async_func
2205{
Howard Hinnant99968442011-11-29 18:15:50 +00002206 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002207
2208public:
Howard Hinnant99968442011-11-29 18:15:50 +00002209 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002210
2211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002212 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002213 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002214
2215 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002216 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002217
Howard Hinnant99968442011-11-29 18:15:50 +00002218 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002219 {
2220 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2221 return __execute(_Index());
2222 }
2223private:
2224 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002225 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002226 __execute(__tuple_indices<_Indices...>)
2227 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002228 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002229 }
2230};
2231
Howard Hinnant99968442011-11-29 18:15:50 +00002232template <class _Fp, class... _Args>
2233future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2234async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002235{
Howard Hinnant99968442011-11-29 18:15:50 +00002236 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2237 typedef typename _BF::_Rp _Rp;
2238 future<_Rp> __r;
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002239 if (int(__policy) & int(launch::async))
Howard Hinnant99968442011-11-29 18:15:50 +00002240 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002241 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002242 else if (int(__policy) & int(launch::deferred))
Howard Hinnant99968442011-11-29 18:15:50 +00002243 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002244 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002245 return __r;
2246}
2247
Howard Hinnant99968442011-11-29 18:15:50 +00002248template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002249inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002250future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2251async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002252{
Howard Hinnant99968442011-11-29 18:15:50 +00002253 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002254 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002255}
2256
2257#endif // _LIBCPP_HAS_NO_VARIADICS
2258
Howard Hinnante6e4d012010-09-03 21:46:37 +00002259// shared_future
2260
Howard Hinnant99968442011-11-29 18:15:50 +00002261template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002262class _LIBCPP_VISIBLE shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002263{
Howard Hinnant99968442011-11-29 18:15:50 +00002264 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002265
2266public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002268 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002269 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002270 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2271 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002272#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002273 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002274 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002275 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002276 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002277 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002278 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002279#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002280 ~shared_future();
2281 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002282#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002284 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002285 {
2286 shared_future(std::move(__rhs)).swap(*this);
2287 return *this;
2288 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002289#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002290
2291 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002293 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002294
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002295 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002296 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002297
2298 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002300 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002301
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002302 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002303 void wait() const {__state_->wait();}
2304 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002306 future_status
2307 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2308 {return __state_->wait_for(__rel_time);}
2309 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002311 future_status
2312 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2313 {return __state_->wait_until(__abs_time);}
2314};
2315
Howard Hinnant99968442011-11-29 18:15:50 +00002316template <class _Rp>
2317shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002318{
2319 if (__state_)
2320 __state_->__release_shared();
2321}
2322
Howard Hinnant99968442011-11-29 18:15:50 +00002323template <class _Rp>
2324shared_future<_Rp>&
2325shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002326{
2327 if (__rhs.__state_)
2328 __rhs.__state_->__add_shared();
2329 if (__state_)
2330 __state_->__release_shared();
2331 __state_ = __rhs.__state_;
2332 return *this;
2333}
2334
Howard Hinnant99968442011-11-29 18:15:50 +00002335template <class _Rp>
2336class _LIBCPP_VISIBLE shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002337{
Howard Hinnant99968442011-11-29 18:15:50 +00002338 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002339
2340public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002341 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002342 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002344 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2345 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002346#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002347 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002348 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002349 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002350 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002351 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002352 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002353#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002354 ~shared_future();
2355 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002356#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002357 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002358 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002359 {
2360 shared_future(std::move(__rhs)).swap(*this);
2361 return *this;
2362 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002363#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002364
2365 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002366 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002367 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002368
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002369 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002370 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002371
2372 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002373 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002374 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002375
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002376 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002377 void wait() const {__state_->wait();}
2378 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002379 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002380 future_status
2381 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2382 {return __state_->wait_for(__rel_time);}
2383 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002384 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002385 future_status
2386 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2387 {return __state_->wait_until(__abs_time);}
2388};
2389
Howard Hinnant99968442011-11-29 18:15:50 +00002390template <class _Rp>
2391shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002392{
2393 if (__state_)
2394 __state_->__release_shared();
2395}
2396
Howard Hinnant99968442011-11-29 18:15:50 +00002397template <class _Rp>
2398shared_future<_Rp&>&
2399shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002400{
2401 if (__rhs.__state_)
2402 __rhs.__state_->__add_shared();
2403 if (__state_)
2404 __state_->__release_shared();
2405 __state_ = __rhs.__state_;
2406 return *this;
2407}
2408
2409template <>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002410class _LIBCPP_VISIBLE shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002411{
2412 __assoc_sub_state* __state_;
2413
2414public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002415 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002416 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002418 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2419 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002420#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002422 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002423 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002424 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002425 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002426 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002427#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002428 ~shared_future();
2429 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002430#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002432 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002433 {
2434 shared_future(std::move(__rhs)).swap(*this);
2435 return *this;
2436 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002437#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002438
2439 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002441 void get() const {__state_->copy();}
2442
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002444 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002445
2446 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002448 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002449
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002451 void wait() const {__state_->wait();}
2452 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002454 future_status
2455 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2456 {return __state_->wait_for(__rel_time);}
2457 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002459 future_status
2460 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2461 {return __state_->wait_until(__abs_time);}
2462};
2463
Howard Hinnant99968442011-11-29 18:15:50 +00002464template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002465inline _LIBCPP_INLINE_VISIBILITY
2466void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002467swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002468{
2469 __x.swap(__y);
2470}
2471
Howard Hinnant99968442011-11-29 18:15:50 +00002472template <class _Rp>
Howard Hinnant7de47902010-11-30 20:23:32 +00002473inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002474shared_future<_Rp>
2475future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002476{
Howard Hinnant99968442011-11-29 18:15:50 +00002477 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002478}
2479
Howard Hinnant99968442011-11-29 18:15:50 +00002480template <class _Rp>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002481inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002482shared_future<_Rp&>
2483future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002484{
Howard Hinnant99968442011-11-29 18:15:50 +00002485 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002486}
2487
Howard Hinnanta4451512010-12-02 16:45:21 +00002488#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2489
Howard Hinnant7de47902010-11-30 20:23:32 +00002490inline _LIBCPP_INLINE_VISIBILITY
2491shared_future<void>
2492future<void>::share()
2493{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002494 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002495}
2496
Howard Hinnanta4451512010-12-02 16:45:21 +00002497#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2498
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002499_LIBCPP_END_NAMESPACE_STD
2500
2501#endif // _LIBCPP_FUTURE