blob: fa8dd8a0d7d7938957f6c7e651e5c75578de6a39 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:161// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:014// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:165//
Howard Hinnantb64f8b02010-11-16 22:09:026// 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:168//
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:5430 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:1633};
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:5543error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:1645
Howard Hinnant8bf01dd2012-07-21 17:46:5546const error_category& future_category() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:1647
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
Howard Hinnant8bf01dd2012-07-21 17:46:5554 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:1656};
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:5565 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:1666 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:5570 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:1671 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:5572 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:1673
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:5595 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:1696 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55102 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16103
104 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19105 future<R&> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16106
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:55123 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55130 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16131
132 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19133 future<void> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16134
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:55144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16145
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:55153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55165 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16166
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:55180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55192 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16193
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:55207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55219 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16220
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:55234 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16235 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55246 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16247
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:55261 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16262 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55273 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16274
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:55288 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16289 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55300 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16301
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:16311template <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:01319template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16320
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:55328 packaged_task() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16329 template <class F>
Howard Hinnantbc8d3f92010-05-11 19:42:16330 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
336 packaged_task(packaged_task&) = delete;
337 packaged_task& operator=(packaged_task&) = delete;
338
339 // move support
Howard Hinnant8bf01dd2012-07-21 17:46:55340 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:16343
Howard Hinnant8bf01dd2012-07-21 17:46:55344 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16345
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:55357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16358
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:19367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37370#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19371#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16372
Howard Hinnant08e17472011-10-17 20:05:10373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16374#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10375#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16376
377_LIBCPP_BEGIN_NAMESPACE_STD
378
379//enum class future_errc
Howard Hinnantf6d875f2011-12-02 19:36:40380_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16381{
Howard Hinnantbc8d3f92010-05-11 19:42:16382 broken_promise,
383 future_already_retrieved,
384 promise_already_satisfied,
385 no_state
386};
Howard Hinnantf6d875f2011-12-02 19:36:40387_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16388
Howard Hinnant8c6cbb22010-09-22 14:16:26389template <>
390struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05391
Howard Hinnantf6d875f2011-12-02 19:36:40392#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:16397//enum class launch
Howard Hinnantf6d875f2011-12-02 19:36:40398_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16399{
Howard Hinnant66895642010-11-23 18:33:54400 async = 1,
401 deferred = 2,
402 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16403};
Howard Hinnantf6d875f2011-12-02 19:36:40404_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16405
406//enum class future_status
Howard Hinnantf6d875f2011-12-02 19:36:40407_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16408{
Howard Hinnantbc8d3f92010-05-11 19:42:16409 ready,
410 timeout,
411 deferred
412};
Howard Hinnantf6d875f2011-12-02 19:36:40413_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16414
Howard Hinnant8c6cbb22010-09-22 14:16:26415_LIBCPP_VISIBLE
Howard Hinnant8bf01dd2012-07-21 17:46:55416const error_category& future_category() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05417
418inline _LIBCPP_INLINE_VISIBILITY
419error_code
Howard Hinnant8bf01dd2012-07-21 17:46:55420make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05421{
422 return error_code(static_cast<int>(__e), future_category());
423}
424
425inline _LIBCPP_INLINE_VISIBILITY
426error_condition
Howard Hinnant8bf01dd2012-07-21 17:46:55427make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05428{
429 return error_condition(static_cast<int>(__e), future_category());
430}
431
Howard Hinnant8c6cbb22010-09-22 14:16:26432class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05433 : public logic_error
434{
435 error_code __ec_;
436public:
437 future_error(error_code __ec);
438
Howard Hinnant8c6cbb22010-09-22 14:16:26439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55440 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52441
442 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05443};
444
Howard Hinnant47499b12010-08-27 20:10:19445class __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:13454 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21455 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19456public:
457 enum
458 {
459 __constructed = 1,
460 __future_attached = 2,
461 ready = 4,
462 deferred = 8
463 };
464
Howard Hinnant8c6cbb22010-09-22 14:16:26465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19466 __assoc_sub_state() : __state_(0) {}
467
Howard Hinnant8c6cbb22010-09-22 14:16:26468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19469 bool __has_value() const
470 {return (__state_ & __constructed) || (__exception_ != nullptr);}
471
Howard Hinnant8c6cbb22010-09-22 14:16:26472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19473 void __set_future_attached() {__state_ |= __future_attached;}
Howard Hinnant8c6cbb22010-09-22 14:16:26474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19475 bool __has_future_attached() const {return __state_ & __future_attached;}
476
Howard Hinnant8c6cbb22010-09-22 14:16:26477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21478 void __set_deferred() {__state_ |= deferred;}
479
Howard Hinnant47499b12010-08-27 20:10:19480 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19482 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:21492 void wait();
Howard Hinnant47499b12010-08-27 20:10:19493 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:21499
500 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19501};
502
Howard Hinnantf39daa82010-08-28 21:01:06503template <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:21508 if (__state_ & deferred)
509 return future_status::deferred;
510 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06511 __cv_.wait_until(__lk, __abs_time);
512 if (__state_ & ready)
513 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06514 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:30522 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06523}
524
Howard Hinnant99968442011-11-29 18:15:50525template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19526class __assoc_state
527 : public __assoc_sub_state
528{
529 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50530 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19531protected:
Howard Hinnant99968442011-11-29 18:15:50532 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19533
Howard Hinnant1694d232011-05-28 14:41:13534 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19535public:
536
537 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19538#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19539 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:19545#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19546 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:50551 _Rp move();
552 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19553};
554
Howard Hinnant99968442011-11-29 18:15:50555template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19556void
Howard Hinnant99968442011-11-29 18:15:50557__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19558{
559 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50560 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19561 delete this;
562}
563
Howard Hinnant99968442011-11-29 18:15:50564template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19565template <class _Arg>
566void
Howard Hinnant73d21a42010-09-04 23:28:19567#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50568__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19569#else
Howard Hinnant99968442011-11-29 18:15:50570__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19571#endif
572{
573 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50574#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19575 if (this->__has_value())
576 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50577#endif
Howard Hinnant99968442011-11-29 18:15:50578 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19579 this->__state_ |= base::__constructed | base::ready;
580 __lk.unlock();
581 __cv_.notify_all();
582}
583
Howard Hinnant99968442011-11-29 18:15:50584template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19585template <class _Arg>
586void
Howard Hinnant73d21a42010-09-04 23:28:19587#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50588__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19589#else
Howard Hinnant99968442011-11-29 18:15:50590__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19591#endif
592{
593 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50594#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19595 if (this->__has_value())
596 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50597#endif
Howard Hinnant99968442011-11-29 18:15:50598 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19599 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04600 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19601 __lk.unlock();
602}
603
Howard Hinnant99968442011-11-29 18:15:50604template <class _Rp>
605_Rp
606__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19607{
608 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21609 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19610 if (this->__exception_ != nullptr)
611 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50612 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19613}
614
Howard Hinnant99968442011-11-29 18:15:50615template <class _Rp>
616typename add_lvalue_reference<_Rp>::type
617__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19618{
619 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21620 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19621 if (this->__exception_ != nullptr)
622 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50623 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19624}
625
Howard Hinnant99968442011-11-29 18:15:50626template <class _Rp>
627class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06628 : public __assoc_sub_state
629{
630 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50631 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06632protected:
Howard Hinnant99968442011-11-29 18:15:50633 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06634
Howard Hinnant1694d232011-05-28 14:41:13635 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06636public:
637
Howard Hinnant99968442011-11-29 18:15:50638 void set_value(_Rp& __arg);
639 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06640
Howard Hinnant99968442011-11-29 18:15:50641 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06642};
643
Howard Hinnant99968442011-11-29 18:15:50644template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06645void
Howard Hinnant99968442011-11-29 18:15:50646__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06647{
648 delete this;
649}
650
Howard Hinnant99968442011-11-29 18:15:50651template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06652void
Howard Hinnant99968442011-11-29 18:15:50653__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06654{
655 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50656#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06657 if (this->__has_value())
658 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50659#endif
Howard Hinnantf39daa82010-08-28 21:01:06660 __value_ = &__arg;
661 this->__state_ |= base::__constructed | base::ready;
662 __lk.unlock();
663 __cv_.notify_all();
664}
665
Howard Hinnant99968442011-11-29 18:15:50666template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06667void
Howard Hinnant99968442011-11-29 18:15:50668__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06669{
670 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50671#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06672 if (this->__has_value())
673 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50674#endif
Howard Hinnantf39daa82010-08-28 21:01:06675 __value_ = &__arg;
676 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04677 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06678 __lk.unlock();
679}
680
Howard Hinnant99968442011-11-29 18:15:50681template <class _Rp>
682_Rp&
683__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06684{
685 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21686 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06687 if (this->__exception_ != nullptr)
688 rethrow_exception(this->__exception_);
689 return *__value_;
690}
691
Howard Hinnant99968442011-11-29 18:15:50692template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19693class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50694 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19695{
Howard Hinnant99968442011-11-29 18:15:50696 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19697 _Alloc __alloc_;
698
Howard Hinnant1694d232011-05-28 14:41:13699 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19700public:
Howard Hinnant8c6cbb22010-09-22 14:16:26701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19702 explicit __assoc_state_alloc(const _Alloc& __a)
703 : __alloc_(__a) {}
704};
705
Howard Hinnant99968442011-11-29 18:15:50706template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19707void
Howard Hinnant99968442011-11-29 18:15:50708__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19709{
710 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50711 reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19712 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:50717template <class _Rp, class _Alloc>
718class __assoc_state_alloc<_Rp&, _Alloc>
719 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06720{
Howard Hinnant99968442011-11-29 18:15:50721 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06722 _Alloc __alloc_;
723
Howard Hinnant1694d232011-05-28 14:41:13724 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06725public:
Howard Hinnant8c6cbb22010-09-22 14:16:26726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06727 explicit __assoc_state_alloc(const _Alloc& __a)
728 : __alloc_(__a) {}
729};
730
Howard Hinnant99968442011-11-29 18:15:50731template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06732void
Howard Hinnant99968442011-11-29 18:15:50733__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06734{
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:19740template <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:13747 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19748public:
Howard Hinnant8c6cbb22010-09-22 14:16:26749 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19750 explicit __assoc_sub_state_alloc(const _Alloc& __a)
751 : __alloc_(__a) {}
752};
753
754template <class _Alloc>
755void
Howard Hinnant1694d232011-05-28 14:41:13756__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19757{
Howard Hinnantf39daa82010-08-28 21:01:06758 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19759 this->~__assoc_sub_state_alloc();
760 __a.deallocate(this, 1);
761}
762
Howard Hinnant99968442011-11-29 18:15:50763template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21764class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50765 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21766{
Howard Hinnant99968442011-11-29 18:15:50767 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21768
Howard Hinnant99968442011-11-29 18:15:50769 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21770
771public:
Howard Hinnant73d21a42010-09-04 23:28:19772#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50773 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21774#endif
775
776 virtual void __execute();
777};
778
Howard Hinnant73d21a42010-09-04 23:28:19779#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21780
Howard Hinnant99968442011-11-29 18:15:50781template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21782inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50783__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
784 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21785{
786 this->__set_deferred();
787}
788
Howard Hinnant73d21a42010-09-04 23:28:19789#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21790
Howard Hinnant99968442011-11-29 18:15:50791template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21792void
Howard Hinnant99968442011-11-29 18:15:50793__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21794{
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:50809template <class _Fp>
810class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21811 : public __assoc_sub_state
812{
813 typedef __assoc_sub_state base;
814
Howard Hinnant99968442011-11-29 18:15:50815 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21816
817public:
Howard Hinnant73d21a42010-09-04 23:28:19818#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50819 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21820#endif
821
822 virtual void __execute();
823};
824
Howard Hinnant73d21a42010-09-04 23:28:19825#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21826
Howard Hinnant99968442011-11-29 18:15:50827template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21828inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50829__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
830 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21831{
832 this->__set_deferred();
833}
834
Howard Hinnant73d21a42010-09-04 23:28:19835#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21836
Howard Hinnant99968442011-11-29 18:15:50837template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21838void
Howard Hinnant99968442011-11-29 18:15:50839__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21840{
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:50856template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04857class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50858 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04859{
Howard Hinnant99968442011-11-29 18:15:50860 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04861
Howard Hinnant99968442011-11-29 18:15:50862 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04863
Howard Hinnant1694d232011-05-28 14:41:13864 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04865public:
866#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50867 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04868#endif
869
870 virtual void __execute();
871};
872
873#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
874
Howard Hinnant99968442011-11-29 18:15:50875template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04876inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50877__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
878 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04879{
880}
881
882#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
883
Howard Hinnant99968442011-11-29 18:15:50884template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04885void
Howard Hinnant99968442011-11-29 18:15:50886__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04887{
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:50902template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04903void
Howard Hinnant99968442011-11-29 18:15:50904__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04905{
906 this->wait();
907 base::__on_zero_shared();
908}
909
Howard Hinnant99968442011-11-29 18:15:50910template <class _Fp>
911class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04912 : public __assoc_sub_state
913{
914 typedef __assoc_sub_state base;
915
Howard Hinnant99968442011-11-29 18:15:50916 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04917
Howard Hinnant1694d232011-05-28 14:41:13918 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04919public:
920#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50921 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04922#endif
923
924 virtual void __execute();
925};
926
927#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
928
Howard Hinnant99968442011-11-29 18:15:50929template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04930inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50931__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
932 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04933{
934}
935
936#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
937
Howard Hinnant99968442011-11-29 18:15:50938template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04939void
Howard Hinnant99968442011-11-29 18:15:50940__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04941{
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:50957template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04958void
Howard Hinnant99968442011-11-29 18:15:50959__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04960{
961 this->wait();
962 base::__on_zero_shared();
963}
964
Howard Hinnant99968442011-11-29 18:15:50965template <class _Rp> class promise;
966template <class _Rp> class shared_future;
Howard Hinnant47499b12010-08-27 20:10:19967
968// future
969
Howard Hinnant99968442011-11-29 18:15:50970template <class _Rp> class future;
Howard Hinnant54da3382010-08-30 18:46:21971
Howard Hinnant99968442011-11-29 18:15:50972template <class _Rp, class _Fp>
973future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19974#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50975__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21976#else
Howard Hinnant99968442011-11-29 18:15:50977__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21978#endif
979
Howard Hinnant99968442011-11-29 18:15:50980template <class _Rp, class _Fp>
981future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04982#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50983__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04984#else
Howard Hinnant99968442011-11-29 18:15:50985__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04986#endif
987
Howard Hinnant99968442011-11-29 18:15:50988template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:26989class _LIBCPP_VISIBLE future
Howard Hinnant47499b12010-08-27 20:10:19990{
Howard Hinnant99968442011-11-29 18:15:50991 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19992
Howard Hinnant99968442011-11-29 18:15:50993 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19994
995 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25996 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21997
Howard Hinnant73d21a42010-09-04 23:28:19998#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50999 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:211003#else
Howard Hinnant99968442011-11-29 18:15:501004 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:211008#endif
1009
Howard Hinnant47499b12010-08-27 20:10:191010public:
Howard Hinnant8c6cbb22010-09-22 14:16:261011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551012 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:191013#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551015 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191016 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1017 future(const future&) = delete;
1018 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:261019 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551020 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191021 {
1022 future(std::move(__rhs)).swap(*this);
1023 return *this;
1024 }
Howard Hinnant73d21a42010-09-04 23:28:191025#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191026private:
1027 future(const future&);
1028 future& operator=(const future&);
1029public:
Howard Hinnant73d21a42010-09-04 23:28:191030#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191031 ~future();
Howard Hinnant99968442011-11-29 18:15:501032 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:191033
1034 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:501035 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:191036
Howard Hinnant8c6cbb22010-09-22 14:16:261037 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551038 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191039
1040 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:261041 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551042 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:191043
Howard Hinnant8c6cbb22010-09-22 14:16:261044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191045 void wait() const {__state_->wait();}
1046 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:261047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191048 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:261052 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191053 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:501058template <class _Rp>
1059future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:191060 : __state_(__state)
1061{
Howard Hinnant22ba71b2011-07-13 16:00:501062#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191063 if (__state_->__has_future_attached())
1064 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:501065#endif
Howard Hinnant47499b12010-08-27 20:10:191066 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:211067 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:191068}
1069
Howard Hinnant54da3382010-08-30 18:46:211070struct __release_shared_count
1071{
1072 void operator()(__shared_count* p) {p->__release_shared();}
1073};
1074
Howard Hinnant99968442011-11-29 18:15:501075template <class _Rp>
1076future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:191077{
1078 if (__state_)
1079 __state_->__release_shared();
1080}
1081
Howard Hinnant99968442011-11-29 18:15:501082template <class _Rp>
1083_Rp
1084future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:191085{
Howard Hinnant54da3382010-08-30 18:46:211086 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:501087 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:191088 __state_ = nullptr;
1089 return __s->move();
1090}
1091
Howard Hinnant99968442011-11-29 18:15:501092template <class _Rp>
1093class _LIBCPP_VISIBLE future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:191094{
Howard Hinnant99968442011-11-29 18:15:501095 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:191096
Howard Hinnant99968442011-11-29 18:15:501097 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:191098
1099 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:251100 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:211101
Howard Hinnant73d21a42010-09-04 23:28:191102#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:501103 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:211107#else
Howard Hinnant99968442011-11-29 18:15:501108 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:211112#endif
1113
Howard Hinnant47499b12010-08-27 20:10:191114public:
Howard Hinnant8c6cbb22010-09-22 14:16:261115 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551116 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:191117#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261118 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551119 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191120 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1121 future(const future&) = delete;
1122 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:261123 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551124 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191125 {
1126 future(std::move(__rhs)).swap(*this);
1127 return *this;
1128 }
Howard Hinnant73d21a42010-09-04 23:28:191129#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191130private:
1131 future(const future&);
1132 future& operator=(const future&);
1133public:
Howard Hinnant73d21a42010-09-04 23:28:191134#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191135 ~future();
Howard Hinnant99968442011-11-29 18:15:501136 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:191137
1138 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:501139 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:191140
Howard Hinnant8c6cbb22010-09-22 14:16:261141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551142 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191143
1144 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:261145 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551146 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:191147
Howard Hinnant8c6cbb22010-09-22 14:16:261148 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191149 void wait() const {__state_->wait();}
1150 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:261151 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191152 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:261156 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191157 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:501162template <class _Rp>
1163future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:191164 : __state_(__state)
1165{
Howard Hinnant22ba71b2011-07-13 16:00:501166#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191167 if (__state_->__has_future_attached())
1168 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:501169#endif
Howard Hinnant47499b12010-08-27 20:10:191170 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:211171 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:191172}
1173
Howard Hinnant99968442011-11-29 18:15:501174template <class _Rp>
1175future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:191176{
1177 if (__state_)
1178 __state_->__release_shared();
1179}
1180
Howard Hinnant99968442011-11-29 18:15:501181template <class _Rp>
1182_Rp&
1183future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:191184{
Howard Hinnant54da3382010-08-30 18:46:211185 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:501186 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:191187 __state_ = nullptr;
1188 return __s->copy();
1189}
1190
1191template <>
Howard Hinnant8c6cbb22010-09-22 14:16:261192class _LIBCPP_VISIBLE future<void>
Howard Hinnant47499b12010-08-27 20:10:191193{
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:251199 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:211200
Howard Hinnant73d21a42010-09-04 23:28:191201#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:501202 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:211206#else
Howard Hinnant99968442011-11-29 18:15:501207 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:211211#endif
1212
Howard Hinnant47499b12010-08-27 20:10:191213public:
Howard Hinnant8c6cbb22010-09-22 14:16:261214 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551215 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:191216#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261217 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551218 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191219 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1220 future(const future&) = delete;
1221 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:261222 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551223 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191224 {
1225 future(std::move(__rhs)).swap(*this);
1226 return *this;
1227 }
Howard Hinnant73d21a42010-09-04 23:28:191228#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191229private:
1230 future(const future&);
1231 future& operator=(const future&);
1232public:
Howard Hinnant73d21a42010-09-04 23:28:191233#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191234 ~future();
Howard Hinnant7de47902010-11-30 20:23:321235 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:191236
1237 // retrieving the value
1238 void get();
1239
Howard Hinnant8c6cbb22010-09-22 14:16:261240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551241 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191242
1243 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:261244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551245 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:191246
Howard Hinnant8c6cbb22010-09-22 14:16:261247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191248 void wait() const {__state_->wait();}
1249 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:261250 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191251 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:261255 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:191256 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:501261template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:251262inline _LIBCPP_INLINE_VISIBILITY
1263void
Howard Hinnant8bf01dd2012-07-21 17:46:551264swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:251265{
1266 __x.swap(__y);
1267}
1268
Howard Hinnant47499b12010-08-27 20:10:191269// promise<R>
1270
Howard Hinnant2b1b2d42011-06-14 19:58:171271template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:211272
Howard Hinnant99968442011-11-29 18:15:501273template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:261274class _LIBCPP_VISIBLE promise
Howard Hinnant47499b12010-08-27 20:10:191275{
Howard Hinnant99968442011-11-29 18:15:501276 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:211277
Howard Hinnant8c6cbb22010-09-22 14:16:261278 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551279 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:211280
1281 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:191282public:
1283 promise();
1284 template <class _Alloc>
1285 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:191286#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261287 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551288 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191289 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1290 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191291#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191292private:
1293 promise(const promise& __rhs);
1294public:
Howard Hinnant73d21a42010-09-04 23:28:191295#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191296 ~promise();
1297
1298 // assignment
Howard Hinnant73d21a42010-09-04 23:28:191299#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551301 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191302 {
1303 promise(std::move(__rhs)).swap(*this);
1304 return *this;
1305 }
1306 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191307#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191308private:
1309 promise& operator=(const promise& __rhs);
1310public:
Howard Hinnant73d21a42010-09-04 23:28:191311#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261312 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551313 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191314
1315 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:501316 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:191317
1318 // setting the result
Howard Hinnant99968442011-11-29 18:15:501319 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:191320#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:501321 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:191322#endif
1323 void set_exception(exception_ptr __p);
1324
1325 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:501326 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:191327#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:501328 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:191329#endif
1330 void set_exception_at_thread_exit(exception_ptr __p);
1331};
1332
Howard Hinnant99968442011-11-29 18:15:501333template <class _Rp>
1334promise<_Rp>::promise()
1335 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:191336{
1337}
1338
Howard Hinnant99968442011-11-29 18:15:501339template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191340template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:501341promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:191342{
Howard Hinnant99968442011-11-29 18:15:501343 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:191344 typedef __allocator_destructor<_A2> _D2;
1345 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:501346 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:191348 __state_ = __hold.release();
1349}
1350
Howard Hinnant99968442011-11-29 18:15:501351template <class _Rp>
1352promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:191353{
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:501364template <class _Rp>
1365future<_Rp>
1366promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:191367{
Howard Hinnant22ba71b2011-07-13 16:00:501368#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191369 if (__state_ == nullptr)
1370 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501371#endif
Howard Hinnant99968442011-11-29 18:15:501372 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:191373}
1374
Howard Hinnant99968442011-11-29 18:15:501375template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191376void
Howard Hinnant99968442011-11-29 18:15:501377promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:191378{
Howard Hinnant22ba71b2011-07-13 16:00:501379#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191380 if (__state_ == nullptr)
1381 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501382#endif
Howard Hinnant47499b12010-08-27 20:10:191383 __state_->set_value(__r);
1384}
1385
Howard Hinnant73d21a42010-09-04 23:28:191386#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191387
Howard Hinnant99968442011-11-29 18:15:501388template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191389void
Howard Hinnant99968442011-11-29 18:15:501390promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:191391{
Howard Hinnant22ba71b2011-07-13 16:00:501392#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191393 if (__state_ == nullptr)
1394 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501395#endif
Howard Hinnant0949eed2011-06-30 21:18:191396 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:191397}
1398
Howard Hinnant73d21a42010-09-04 23:28:191399#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191400
Howard Hinnant99968442011-11-29 18:15:501401template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191402void
Howard Hinnant99968442011-11-29 18:15:501403promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:191404{
Howard Hinnant22ba71b2011-07-13 16:00:501405#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191406 if (__state_ == nullptr)
1407 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501408#endif
Howard Hinnant47499b12010-08-27 20:10:191409 __state_->set_exception(__p);
1410}
1411
Howard Hinnant99968442011-11-29 18:15:501412template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191413void
Howard Hinnant99968442011-11-29 18:15:501414promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:191415{
Howard Hinnant22ba71b2011-07-13 16:00:501416#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191417 if (__state_ == nullptr)
1418 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501419#endif
Howard Hinnant47499b12010-08-27 20:10:191420 __state_->set_value_at_thread_exit(__r);
1421}
1422
Howard Hinnant73d21a42010-09-04 23:28:191423#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191424
Howard Hinnant99968442011-11-29 18:15:501425template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191426void
Howard Hinnant99968442011-11-29 18:15:501427promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:191428{
Howard Hinnant22ba71b2011-07-13 16:00:501429#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191430 if (__state_ == nullptr)
1431 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501432#endif
Howard Hinnant0949eed2011-06-30 21:18:191433 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:191434}
1435
Howard Hinnant73d21a42010-09-04 23:28:191436#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191437
Howard Hinnant99968442011-11-29 18:15:501438template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191439void
Howard Hinnant99968442011-11-29 18:15:501440promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:191441{
Howard Hinnant22ba71b2011-07-13 16:00:501442#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191443 if (__state_ == nullptr)
1444 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501445#endif
Howard Hinnant47499b12010-08-27 20:10:191446 __state_->set_exception_at_thread_exit(__p);
1447}
1448
1449// promise<R&>
1450
Howard Hinnant99968442011-11-29 18:15:501451template <class _Rp>
1452class _LIBCPP_VISIBLE promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:191453{
Howard Hinnant99968442011-11-29 18:15:501454 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:211455
Howard Hinnant8c6cbb22010-09-22 14:16:261456 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551457 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:211458
1459 template <class> friend class packaged_task;
1460
Howard Hinnant47499b12010-08-27 20:10:191461public:
1462 promise();
1463 template <class _Allocator>
1464 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:191465#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551467 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191468 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1469 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191470#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191471private:
1472 promise(const promise& __rhs);
1473public:
Howard Hinnant73d21a42010-09-04 23:28:191474#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191475 ~promise();
1476
1477 // assignment
Howard Hinnant73d21a42010-09-04 23:28:191478#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261479 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551480 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191481 {
1482 promise(std::move(__rhs)).swap(*this);
1483 return *this;
1484 }
1485 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191486#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191487private:
1488 promise& operator=(const promise& __rhs);
1489public:
Howard Hinnant73d21a42010-09-04 23:28:191490#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261491 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551492 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191493
1494 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:501495 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:191496
1497 // setting the result
Howard Hinnant99968442011-11-29 18:15:501498 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:191499 void set_exception(exception_ptr __p);
1500
1501 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:501502 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:191503 void set_exception_at_thread_exit(exception_ptr __p);
1504};
1505
Howard Hinnant99968442011-11-29 18:15:501506template <class _Rp>
1507promise<_Rp&>::promise()
1508 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:191509{
1510}
1511
Howard Hinnant99968442011-11-29 18:15:501512template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191513template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:501514promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:191515{
Howard Hinnant99968442011-11-29 18:15:501516 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:191517 typedef __allocator_destructor<_A2> _D2;
1518 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:501519 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:191521 __state_ = __hold.release();
1522}
1523
Howard Hinnant99968442011-11-29 18:15:501524template <class _Rp>
1525promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:191526{
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:501537template <class _Rp>
1538future<_Rp&>
1539promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:191540{
Howard Hinnant22ba71b2011-07-13 16:00:501541#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191542 if (__state_ == nullptr)
1543 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501544#endif
Howard Hinnant99968442011-11-29 18:15:501545 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:191546}
1547
Howard Hinnant99968442011-11-29 18:15:501548template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191549void
Howard Hinnant99968442011-11-29 18:15:501550promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:191551{
Howard Hinnant22ba71b2011-07-13 16:00:501552#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191553 if (__state_ == nullptr)
1554 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501555#endif
Howard Hinnant47499b12010-08-27 20:10:191556 __state_->set_value(__r);
1557}
1558
Howard Hinnant99968442011-11-29 18:15:501559template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191560void
Howard Hinnant99968442011-11-29 18:15:501561promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:191562{
Howard Hinnant22ba71b2011-07-13 16:00:501563#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191564 if (__state_ == nullptr)
1565 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501566#endif
Howard Hinnant47499b12010-08-27 20:10:191567 __state_->set_exception(__p);
1568}
1569
Howard Hinnant99968442011-11-29 18:15:501570template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191571void
Howard Hinnant99968442011-11-29 18:15:501572promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:191573{
Howard Hinnant22ba71b2011-07-13 16:00:501574#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191575 if (__state_ == nullptr)
1576 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501577#endif
Howard Hinnant47499b12010-08-27 20:10:191578 __state_->set_value_at_thread_exit(__r);
1579}
1580
Howard Hinnant99968442011-11-29 18:15:501581template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191582void
Howard Hinnant99968442011-11-29 18:15:501583promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:191584{
Howard Hinnant22ba71b2011-07-13 16:00:501585#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:191586 if (__state_ == nullptr)
1587 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:501588#endif
Howard Hinnant47499b12010-08-27 20:10:191589 __state_->set_exception_at_thread_exit(__p);
1590}
1591
1592// promise<void>
1593
1594template <>
Howard Hinnant8c6cbb22010-09-22 14:16:261595class _LIBCPP_VISIBLE promise<void>
Howard Hinnant47499b12010-08-27 20:10:191596{
1597 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:211598
Howard Hinnant8c6cbb22010-09-22 14:16:261599 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551600 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:211601
1602 template <class> friend class packaged_task;
1603
Howard Hinnant47499b12010-08-27 20:10:191604public:
1605 promise();
1606 template <class _Allocator>
1607 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:191608#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261609 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551610 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191611 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1612 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191613#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191614private:
1615 promise(const promise& __rhs);
1616public:
Howard Hinnant73d21a42010-09-04 23:28:191617#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191618 ~promise();
1619
1620 // assignment
Howard Hinnant73d21a42010-09-04 23:28:191621#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551623 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191624 {
1625 promise(std::move(__rhs)).swap(*this);
1626 return *this;
1627 }
1628 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:191629#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:191630private:
1631 promise& operator=(const promise& __rhs);
1632public:
Howard Hinnant73d21a42010-09-04 23:28:191633#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:261634 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551635 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:191636
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:501660template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:191661inline _LIBCPP_INLINE_VISIBILITY
1662void
Howard Hinnant8bf01dd2012-07-21 17:46:551663swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:191664{
1665 __x.swap(__y);
1666}
1667
Howard Hinnant99968442011-11-29 18:15:501668template <class _Rp, class _Alloc>
1669 struct _LIBCPP_VISIBLE uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:261670 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:191671
Howard Hinnant54da3382010-08-30 18:46:211672#ifndef _LIBCPP_HAS_NO_VARIADICS
1673
1674// packaged_task
1675
1676template<class _Fp> class __packaged_task_base;
1677
Howard Hinnant99968442011-11-29 18:15:501678template<class _Rp, class ..._ArgTypes>
1679class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:211680{
1681 __packaged_task_base(const __packaged_task_base&);
1682 __packaged_task_base& operator=(const __packaged_task_base&);
1683public:
Howard Hinnant8c6cbb22010-09-22 14:16:261684 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211685 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:261686 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211687 virtual ~__packaged_task_base() {}
Howard Hinnant8bf01dd2012-07-21 17:46:551688 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnant54da3382010-08-30 18:46:211689 virtual void destroy() = 0;
1690 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:501691 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:211692};
1693
1694template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1695
Howard Hinnant99968442011-11-29 18:15:501696template<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:211699{
Howard Hinnant99968442011-11-29 18:15:501700 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:211701public:
Howard Hinnant8c6cbb22010-09-22 14:16:261702 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:501703 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:501705 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:501707 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:211708 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261709 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:501710 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:191711 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant8bf01dd2012-07-21 17:46:551712 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:211713 virtual void destroy();
1714 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:501715 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:211716};
1717
Howard Hinnant99968442011-11-29 18:15:501718template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:211719void
Howard Hinnant99968442011-11-29 18:15:501720__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant8bf01dd2012-07-21 17:46:551721 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:211722{
Howard Hinnant0949eed2011-06-30 21:18:191723 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:211724}
1725
Howard Hinnant99968442011-11-29 18:15:501726template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:211727void
Howard Hinnant99968442011-11-29 18:15:501728__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:211729{
Howard Hinnant99968442011-11-29 18:15:501730 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:211731}
1732
Howard Hinnant99968442011-11-29 18:15:501733template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:211734void
Howard Hinnant99968442011-11-29 18:15:501735__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:211736{
Howard Hinnant99968442011-11-29 18:15:501737 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:211740 __a.deallocate(this, 1);
1741}
1742
Howard Hinnant99968442011-11-29 18:15:501743template<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:211746{
Howard Hinnant0949eed2011-06-30 21:18:191747 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:211748}
1749
Howard Hinnant2b1b2d42011-06-14 19:58:171750template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:211751
Howard Hinnant99968442011-11-29 18:15:501752template<class _Rp, class ..._ArgTypes>
1753class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:211754{
Howard Hinnant99968442011-11-29 18:15:501755 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant54da3382010-08-30 18:46:211756 aligned_storage<3*sizeof(void*)>::type __buf_;
1757 __base* __f_;
1758
1759public:
Howard Hinnant99968442011-11-29 18:15:501760 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:211761
1762 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:261763 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551764 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:501765 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:211769
Howard Hinnant8bf01dd2012-07-21 17:46:551770 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1771 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:211772
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:551778 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:211779
Howard Hinnant99968442011-11-29 18:15:501780 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:211781};
1782
Howard Hinnant99968442011-11-29 18:15:501783template<class _Rp, class ..._ArgTypes>
Howard Hinnant8bf01dd2012-07-21 17:46:551784__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:211785{
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:501800template<class _Rp, class ..._ArgTypes>
1801template <class _Fp>
1802__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:211803 : __f_(nullptr)
1804{
Howard Hinnant99968442011-11-29 18:15:501805 typedef typename remove_reference<_Fp>::type _FR;
1806 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:211807 if (sizeof(_FF) <= sizeof(__buf_))
1808 {
1809 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:501810 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:211811 }
1812 else
1813 {
Howard Hinnant99968442011-11-29 18:15:501814 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:211819 __f_ = __hold.release();
1820 }
1821}
1822
Howard Hinnant99968442011-11-29 18:15:501823template<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:211827 : __f_(nullptr)
1828{
1829 typedef allocator_traits<_Alloc> __alloc_traits;
Howard Hinnant99968442011-11-29 18:15:501830 typedef typename remove_reference<_Fp>::type _FR;
1831 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:211832 if (sizeof(_FF) <= sizeof(__buf_))
1833 {
1834 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:501835 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:211836 }
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:501845 _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:211850 __f_ = __hold.release();
1851 }
1852}
1853
Howard Hinnant99968442011-11-29 18:15:501854template<class _Rp, class ..._ArgTypes>
1855__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant8bf01dd2012-07-21 17:46:551856__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:211857{
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 }
1875}
1876
Howard Hinnant99968442011-11-29 18:15:501877template<class _Rp, class ..._ArgTypes>
1878__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:211879{
1880 if (__f_ == (__base*)&__buf_)
1881 __f_->destroy();
1882 else if (__f_)
1883 __f_->destroy_deallocate();
1884}
1885
Howard Hinnant99968442011-11-29 18:15:501886template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:211887void
Howard Hinnant8bf01dd2012-07-21 17:46:551888__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:211889{
1890 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1891 {
1892 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1893 __base* __t = (__base*)&__tempbuf;
1894 __f_->__move_to(__t);
1895 __f_->destroy();
1896 __f_ = nullptr;
1897 __f.__f_->__move_to((__base*)&__buf_);
1898 __f.__f_->destroy();
1899 __f.__f_ = nullptr;
1900 __f_ = (__base*)&__buf_;
1901 __t->__move_to((__base*)&__f.__buf_);
1902 __t->destroy();
1903 __f.__f_ = (__base*)&__f.__buf_;
1904 }
1905 else if (__f_ == (__base*)&__buf_)
1906 {
1907 __f_->__move_to((__base*)&__f.__buf_);
1908 __f_->destroy();
1909 __f_ = __f.__f_;
1910 __f.__f_ = (__base*)&__f.__buf_;
1911 }
1912 else if (__f.__f_ == (__base*)&__f.__buf_)
1913 {
1914 __f.__f_->__move_to((__base*)&__buf_);
1915 __f.__f_->destroy();
1916 __f.__f_ = __f_;
1917 __f_ = (__base*)&__buf_;
1918 }
1919 else
Howard Hinnant0949eed2011-06-30 21:18:191920 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:211921}
1922
Howard Hinnant99968442011-11-29 18:15:501923template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:211924inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:501925_Rp
1926__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:211927{
Howard Hinnant0949eed2011-06-30 21:18:191928 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:211929}
1930
Howard Hinnant99968442011-11-29 18:15:501931template<class _Rp, class ..._ArgTypes>
1932class _LIBCPP_VISIBLE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:211933{
1934public:
Howard Hinnant99968442011-11-29 18:15:501935 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:211936
1937private:
1938 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1939 promise<result_type> __p_;
1940
1941public:
1942 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:261943 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551944 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:501945 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:261946 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:501947 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
1948 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:261949 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:501950 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1951 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:211952 __p_(allocator_arg, __a) {}
1953 // ~packaged_task() = default;
1954
1955 // no copy
1956 packaged_task(packaged_task&) = delete;
1957 packaged_task& operator=(packaged_task&) = delete;
1958
1959 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:261960 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551961 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:191962 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:261963 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551964 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:211965 {
Howard Hinnant0949eed2011-06-30 21:18:191966 __f_ = _VSTD::move(__other.__f_);
1967 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:211968 return *this;
1969 }
Howard Hinnant8c6cbb22010-09-22 14:16:261970 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551971 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:211972 {
1973 __f_.swap(__other.__f_);
1974 __p_.swap(__other.__p_);
1975 }
1976
Howard Hinnant8c6cbb22010-09-22 14:16:261977 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:551978 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:211979
1980 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:261981 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:211982 future<result_type> get_future() {return __p_.get_future();}
1983
1984 // execution
1985 void operator()(_ArgTypes... __args);
1986 void make_ready_at_thread_exit(_ArgTypes... __args);
1987
1988 void reset();
1989};
1990
Howard Hinnant99968442011-11-29 18:15:501991template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:211992void
Howard Hinnant99968442011-11-29 18:15:501993packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:211994{
1995#ifndef _LIBCPP_NO_EXCEPTIONS
1996 if (__p_.__state_ == nullptr)
1997 throw future_error(make_error_code(future_errc::no_state));
1998 if (__p_.__state_->__has_value())
1999 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2000 try
2001 {
2002#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192003 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:212004#ifndef _LIBCPP_NO_EXCEPTIONS
2005 }
2006 catch (...)
2007 {
2008 __p_.set_exception(current_exception());
2009 }
2010#endif // _LIBCPP_NO_EXCEPTIONS
2011}
2012
Howard Hinnant99968442011-11-29 18:15:502013template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:212014void
Howard Hinnant99968442011-11-29 18:15:502015packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:212016{
2017#ifndef _LIBCPP_NO_EXCEPTIONS
2018 if (__p_.__state_ == nullptr)
2019 throw future_error(make_error_code(future_errc::no_state));
2020 if (__p_.__state_->__has_value())
2021 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2022 try
2023 {
2024#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192025 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:212026#ifndef _LIBCPP_NO_EXCEPTIONS
2027 }
2028 catch (...)
2029 {
2030 __p_.set_exception_at_thread_exit(current_exception());
2031 }
2032#endif // _LIBCPP_NO_EXCEPTIONS
2033}
2034
Howard Hinnant99968442011-11-29 18:15:502035template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:212036void
Howard Hinnant99968442011-11-29 18:15:502037packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:212038{
2039#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:322040 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:212041 throw future_error(make_error_code(future_errc::no_state));
2042#endif // _LIBCPP_NO_EXCEPTIONS
2043 __p_ = promise<result_type>();
2044}
2045
2046template<class ..._ArgTypes>
Howard Hinnant8c6cbb22010-09-22 14:16:262047class _LIBCPP_VISIBLE packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:212048{
2049public:
2050 typedef void result_type;
2051
2052private:
2053 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2054 promise<result_type> __p_;
2055
2056public:
2057 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:262058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552059 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:502060 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:262061 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502062 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2063 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:262064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502065 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2066 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:212067 __p_(allocator_arg, __a) {}
2068 // ~packaged_task() = default;
2069
2070 // no copy
2071 packaged_task(packaged_task&) = delete;
2072 packaged_task& operator=(packaged_task&) = delete;
2073
2074 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:262075 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552076 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:192077 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262078 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552079 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:212080 {
Howard Hinnant0949eed2011-06-30 21:18:192081 __f_ = _VSTD::move(__other.__f_);
2082 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:212083 return *this;
2084 }
Howard Hinnant8c6cbb22010-09-22 14:16:262085 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552086 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:212087 {
2088 __f_.swap(__other.__f_);
2089 __p_.swap(__other.__p_);
2090 }
2091
Howard Hinnant8c6cbb22010-09-22 14:16:262092 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552093 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:212094
2095 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:262096 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:212097 future<result_type> get_future() {return __p_.get_future();}
2098
2099 // execution
2100 void operator()(_ArgTypes... __args);
2101 void make_ready_at_thread_exit(_ArgTypes... __args);
2102
2103 void reset();
2104};
2105
2106template<class ..._ArgTypes>
2107void
2108packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2109{
2110#ifndef _LIBCPP_NO_EXCEPTIONS
2111 if (__p_.__state_ == nullptr)
2112 throw future_error(make_error_code(future_errc::no_state));
2113 if (__p_.__state_->__has_value())
2114 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2115 try
2116 {
2117#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192118 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:212119 __p_.set_value();
2120#ifndef _LIBCPP_NO_EXCEPTIONS
2121 }
2122 catch (...)
2123 {
2124 __p_.set_exception(current_exception());
2125 }
2126#endif // _LIBCPP_NO_EXCEPTIONS
2127}
2128
2129template<class ..._ArgTypes>
2130void
2131packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2132{
2133#ifndef _LIBCPP_NO_EXCEPTIONS
2134 if (__p_.__state_ == nullptr)
2135 throw future_error(make_error_code(future_errc::no_state));
2136 if (__p_.__state_->__has_value())
2137 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2138 try
2139 {
2140#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:192141 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:212142 __p_.set_value_at_thread_exit();
2143#ifndef _LIBCPP_NO_EXCEPTIONS
2144 }
2145 catch (...)
2146 {
2147 __p_.set_exception_at_thread_exit(current_exception());
2148 }
2149#endif // _LIBCPP_NO_EXCEPTIONS
2150}
2151
2152template<class ..._ArgTypes>
2153void
2154packaged_task<void(_ArgTypes...)>::reset()
2155{
2156#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:322157 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:212158 throw future_error(make_error_code(future_errc::no_state));
2159#endif // _LIBCPP_NO_EXCEPTIONS
2160 __p_ = promise<result_type>();
2161}
2162
2163template <class _Callable>
2164inline _LIBCPP_INLINE_VISIBILITY
2165void
Howard Hinnant8bf01dd2012-07-21 17:46:552166swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:212167{
2168 __x.swap(__y);
2169}
2170
2171template <class _Callable, class _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:262172struct _LIBCPP_VISIBLE uses_allocator<packaged_task<_Callable>, _Alloc>
2173 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:212174
Howard Hinnant99968442011-11-29 18:15:502175template <class _Rp, class _Fp>
2176future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:192177#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:502178__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:212179#else
Howard Hinnant99968442011-11-29 18:15:502180__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:212181#endif
2182{
Howard Hinnant99968442011-11-29 18:15:502183 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2184 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2185 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:212186}
2187
Howard Hinnant99968442011-11-29 18:15:502188template <class _Rp, class _Fp>
2189future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:042190#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:502191__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:042192#else
Howard Hinnant99968442011-11-29 18:15:502193__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:042194#endif
2195{
Howard Hinnant99968442011-11-29 18:15:502196 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2197 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2198 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2199 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:042200}
2201
Howard Hinnant99968442011-11-29 18:15:502202template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:042203class __async_func
2204{
Howard Hinnant99968442011-11-29 18:15:502205 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:042206
2207public:
Howard Hinnant99968442011-11-29 18:15:502208 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:042209
2210 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502211 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:192212 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:042213
2214 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:192215 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:042216
Howard Hinnant99968442011-11-29 18:15:502217 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:042218 {
2219 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2220 return __execute(_Index());
2221 }
2222private:
2223 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:502224 _Rp
Howard Hinnant57cff292011-05-19 15:05:042225 __execute(__tuple_indices<_Indices...>)
2226 {
Howard Hinnant0949eed2011-06-30 21:18:192227 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:042228 }
2229};
2230
Howard Hinnant99968442011-11-29 18:15:502231template <class _Fp, class... _Args>
2232future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2233async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:212234{
Howard Hinnant99968442011-11-29 18:15:502235 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2236 typedef typename _BF::_Rp _Rp;
2237 future<_Rp> __r;
Howard Hinnantf6d875f2011-12-02 19:36:402238 if (int(__policy) & int(launch::async))
Howard Hinnant99968442011-11-29 18:15:502239 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:192240 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnantf6d875f2011-12-02 19:36:402241 else if (int(__policy) & int(launch::deferred))
Howard Hinnant99968442011-11-29 18:15:502242 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:192243 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:212244 return __r;
2245}
2246
Howard Hinnant99968442011-11-29 18:15:502247template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:212248inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502249future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2250async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:212251{
Howard Hinnant99968442011-11-29 18:15:502252 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:192253 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:212254}
2255
2256#endif // _LIBCPP_HAS_NO_VARIADICS
2257
Howard Hinnante6e4d012010-09-03 21:46:372258// shared_future
2259
Howard Hinnant99968442011-11-29 18:15:502260template <class _Rp>
Howard Hinnant8c6cbb22010-09-22 14:16:262261class _LIBCPP_VISIBLE shared_future
Howard Hinnant99be8232010-09-03 18:39:252262{
Howard Hinnant99968442011-11-29 18:15:502263 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:252264
2265public:
Howard Hinnant8c6cbb22010-09-22 14:16:262266 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552267 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262268 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252269 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2270 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:192271#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262272 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552273 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:252274 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:262275 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552276 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:252277 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:192278#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252279 ~shared_future();
2280 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:192281#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262282 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552283 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:252284 {
2285 shared_future(std::move(__rhs)).swap(*this);
2286 return *this;
2287 }
Howard Hinnant73d21a42010-09-04 23:28:192288#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252289
2290 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:262291 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502292 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:252293
Howard Hinnant8c6cbb22010-09-22 14:16:262294 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552295 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:252296
2297 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:262298 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552299 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:252300
Howard Hinnant8c6cbb22010-09-22 14:16:262301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252302 void wait() const {__state_->wait();}
2303 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:262304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252305 future_status
2306 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2307 {return __state_->wait_for(__rel_time);}
2308 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:262309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252310 future_status
2311 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2312 {return __state_->wait_until(__abs_time);}
2313};
2314
Howard Hinnant99968442011-11-29 18:15:502315template <class _Rp>
2316shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:252317{
2318 if (__state_)
2319 __state_->__release_shared();
2320}
2321
Howard Hinnant99968442011-11-29 18:15:502322template <class _Rp>
2323shared_future<_Rp>&
2324shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:252325{
2326 if (__rhs.__state_)
2327 __rhs.__state_->__add_shared();
2328 if (__state_)
2329 __state_->__release_shared();
2330 __state_ = __rhs.__state_;
2331 return *this;
2332}
2333
Howard Hinnant99968442011-11-29 18:15:502334template <class _Rp>
2335class _LIBCPP_VISIBLE shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:252336{
Howard Hinnant99968442011-11-29 18:15:502337 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:252338
2339public:
Howard Hinnant8c6cbb22010-09-22 14:16:262340 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552341 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262342 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252343 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2344 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:192345#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262346 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552347 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:252348 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:262349 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552350 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:252351 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:192352#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252353 ~shared_future();
2354 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:192355#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262356 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552357 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:252358 {
2359 shared_future(std::move(__rhs)).swap(*this);
2360 return *this;
2361 }
Howard Hinnant73d21a42010-09-04 23:28:192362#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252363
2364 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:262365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502366 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:252367
Howard Hinnant8c6cbb22010-09-22 14:16:262368 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552369 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:252370
2371 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:262372 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552373 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:252374
Howard Hinnant8c6cbb22010-09-22 14:16:262375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252376 void wait() const {__state_->wait();}
2377 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:262378 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252379 future_status
2380 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2381 {return __state_->wait_for(__rel_time);}
2382 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:262383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252384 future_status
2385 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2386 {return __state_->wait_until(__abs_time);}
2387};
2388
Howard Hinnant99968442011-11-29 18:15:502389template <class _Rp>
2390shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:252391{
2392 if (__state_)
2393 __state_->__release_shared();
2394}
2395
Howard Hinnant99968442011-11-29 18:15:502396template <class _Rp>
2397shared_future<_Rp&>&
2398shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:252399{
2400 if (__rhs.__state_)
2401 __rhs.__state_->__add_shared();
2402 if (__state_)
2403 __state_->__release_shared();
2404 __state_ = __rhs.__state_;
2405 return *this;
2406}
2407
2408template <>
Howard Hinnant8c6cbb22010-09-22 14:16:262409class _LIBCPP_VISIBLE shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:252410{
2411 __assoc_sub_state* __state_;
2412
2413public:
Howard Hinnant8c6cbb22010-09-22 14:16:262414 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552415 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:262416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252417 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2418 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:192419#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552421 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:252422 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:262423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552424 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:252425 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:192426#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252427 ~shared_future();
2428 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:192429#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:262430 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552431 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:252432 {
2433 shared_future(std::move(__rhs)).swap(*this);
2434 return *this;
2435 }
Howard Hinnant73d21a42010-09-04 23:28:192436#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:252437
2438 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:262439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252440 void get() const {__state_->copy();}
2441
Howard Hinnant8c6cbb22010-09-22 14:16:262442 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552443 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:252444
2445 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:262446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:552447 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:252448
Howard Hinnant8c6cbb22010-09-22 14:16:262449 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252450 void wait() const {__state_->wait();}
2451 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:262452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252453 future_status
2454 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2455 {return __state_->wait_for(__rel_time);}
2456 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:262457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:252458 future_status
2459 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2460 {return __state_->wait_until(__abs_time);}
2461};
2462
Howard Hinnant99968442011-11-29 18:15:502463template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:252464inline _LIBCPP_INLINE_VISIBILITY
2465void
Howard Hinnant8bf01dd2012-07-21 17:46:552466swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:252467{
2468 __x.swap(__y);
2469}
2470
Howard Hinnant99968442011-11-29 18:15:502471template <class _Rp>
Howard Hinnant7de47902010-11-30 20:23:322472inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502473shared_future<_Rp>
2474future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:372475{
Howard Hinnant99968442011-11-29 18:15:502476 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:372477}
2478
Howard Hinnant99968442011-11-29 18:15:502479template <class _Rp>
Howard Hinnante6e4d012010-09-03 21:46:372480inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:502481shared_future<_Rp&>
2482future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:372483{
Howard Hinnant99968442011-11-29 18:15:502484 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:322485}
2486
Howard Hinnanta4451512010-12-02 16:45:212487#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2488
Howard Hinnant7de47902010-11-30 20:23:322489inline _LIBCPP_INLINE_VISIBILITY
2490shared_future<void>
2491future<void>::share()
2492{
Howard Hinnant0949eed2011-06-30 21:18:192493 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:372494}
2495
Howard Hinnanta4451512010-12-02 16:45:212496#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2497
Howard Hinnantbc8d3f92010-05-11 19:42:162498_LIBCPP_END_NAMESPACE_STD
2499
2500#endif // _LIBCPP_FUTURE