blob: 3d7bb6c9d04521bfc8c06c03bb1359567e0931eb [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
22 broken_promise,
23 future_already_retrieved,
24 promise_already_satisfied,
25 no_state
26};
27
28enum class launch
29{
Howard Hinnant66895642010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000033};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000045
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000056};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000073
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant47499b12010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000311template <class F, class... Args>
312 future<typename result_of<F(Args...)>::type>
313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
316 future<typename result_of<F(Args...)>::type>
317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantf5256e12010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
325 typedef R result_type;
326
327 // construction and destruction
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
332 explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333 ~packaged_task();
334
335 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000340 packaged_task(packaged_task&& other) noexcept;
341 packaged_task& operator=(packaged_task&& other) noexcept;
342 void swap(packaged_task& other) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000343
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000358
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant47499b12010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6e4d012010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant47499b12010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372
Howard Hinnant08e17472011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000375#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376
377_LIBCPP_BEGIN_NAMESPACE_STD
378
379//enum class future_errc
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000380_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000381{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000382 broken_promise,
383 future_already_retrieved,
384 promise_already_satisfied,
385 no_state
386};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000387_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000388
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000389template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000390struct _LIBCPP_TYPE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnanta6521722010-08-25 17:32:05 +0000391
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000392#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
393template <>
Howard Hinnant83eade62013-03-06 23:30:19 +0000394struct _LIBCPP_TYPE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000395#endif
396
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000397//enum class launch
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000398_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000399{
Howard Hinnant66895642010-11-23 18:33:54 +0000400 async = 1,
401 deferred = 2,
402 any = async | deferred
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000404_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000405
406//enum class future_status
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000407_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000408{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409 ready,
410 timeout,
411 deferred
412};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000413_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414
Howard Hinnant83eade62013-03-06 23:30:19 +0000415_LIBCPP_FUNC_VIS
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000416const error_category& future_category() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000417
418inline _LIBCPP_INLINE_VISIBILITY
419error_code
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000420make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000421{
422 return error_code(static_cast<int>(__e), future_category());
423}
424
425inline _LIBCPP_INLINE_VISIBILITY
426error_condition
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000427make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000428{
429 return error_condition(static_cast<int>(__e), future_category());
430}
431
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000432class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000433 : public logic_error
434{
435 error_code __ec_;
436public:
437 future_error(error_code __ec);
438
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000440 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52 +0000441
442 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000443};
444
Howard Hinnant47499b12010-08-27 20:10:19 +0000445class __assoc_sub_state
446 : public __shared_count
447{
448protected:
449 exception_ptr __exception_;
450 mutable mutex __mut_;
451 mutable condition_variable __cv_;
452 unsigned __state_;
453
Howard Hinnant1694d232011-05-28 14:41:13 +0000454 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000455 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000456public:
457 enum
458 {
459 __constructed = 1,
460 __future_attached = 2,
461 ready = 4,
462 deferred = 8
463 };
464
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000465 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000466 __assoc_sub_state() : __state_(0) {}
467
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000469 bool __has_value() const
470 {return (__state_ & __constructed) || (__exception_ != nullptr);}
471
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1b031c92013-01-14 20:01:24 +0000473 void __set_future_attached()
474 {
475 lock_guard<mutex> __lk(__mut_);
476 __state_ |= __future_attached;
477 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000479 bool __has_future_attached() const {return __state_ & __future_attached;}
480
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000482 void __set_deferred() {__state_ |= deferred;}
483
Howard Hinnant47499b12010-08-27 20:10:19 +0000484 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000485 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000486 bool __is_ready() const {return __state_ & ready;}
487
488 void set_value();
489 void set_value_at_thread_exit();
490
491 void set_exception(exception_ptr __p);
492 void set_exception_at_thread_exit(exception_ptr __p);
493
494 void copy();
495
Howard Hinnant54da3382010-08-30 18:46:21 +0000496 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000497 template <class _Rep, class _Period>
498 future_status
499 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
500 template <class _Clock, class _Duration>
501 future_status
502 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000503
504 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000505};
506
Howard Hinnantf39daa82010-08-28 21:01:06 +0000507template <class _Clock, class _Duration>
508future_status
509__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
510{
511 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000512 if (__state_ & deferred)
513 return future_status::deferred;
514 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000515 __cv_.wait_until(__lk, __abs_time);
516 if (__state_ & ready)
517 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000518 return future_status::timeout;
519}
520
521template <class _Rep, class _Period>
522inline _LIBCPP_INLINE_VISIBILITY
523future_status
524__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
525{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000526 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000527}
528
Howard Hinnant99968442011-11-29 18:15:50 +0000529template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000530class __assoc_state
531 : public __assoc_sub_state
532{
533 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000534 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000535protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000536 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000537
Howard Hinnant1694d232011-05-28 14:41:13 +0000538 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000539public:
540
541 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000542#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000543 void set_value(_Arg&& __arg);
544#else
545 void set_value(_Arg& __arg);
546#endif
547
548 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000549#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000550 void set_value_at_thread_exit(_Arg&& __arg);
551#else
552 void set_value_at_thread_exit(_Arg& __arg);
553#endif
554
Howard Hinnant99968442011-11-29 18:15:50 +0000555 _Rp move();
556 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000557};
558
Howard Hinnant99968442011-11-29 18:15:50 +0000559template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000560void
Howard Hinnant99968442011-11-29 18:15:50 +0000561__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000562{
563 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000564 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000565 delete this;
566}
567
Howard Hinnant99968442011-11-29 18:15:50 +0000568template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000569template <class _Arg>
570void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000571#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000572__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000573#else
Howard Hinnant99968442011-11-29 18:15:50 +0000574__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000575#endif
576{
577 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000578#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000579 if (this->__has_value())
580 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000581#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000582 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000583 this->__state_ |= base::__constructed | base::ready;
584 __lk.unlock();
585 __cv_.notify_all();
586}
587
Howard Hinnant99968442011-11-29 18:15:50 +0000588template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000589template <class _Arg>
590void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000591#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000592__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000593#else
Howard Hinnant99968442011-11-29 18:15:50 +0000594__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000595#endif
596{
597 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000598#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000599 if (this->__has_value())
600 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000601#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000602 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000603 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000604 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000605 __lk.unlock();
606}
607
Howard Hinnant99968442011-11-29 18:15:50 +0000608template <class _Rp>
609_Rp
610__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000611{
612 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000613 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000614 if (this->__exception_ != nullptr)
615 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000616 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000617}
618
Howard Hinnant99968442011-11-29 18:15:50 +0000619template <class _Rp>
620typename add_lvalue_reference<_Rp>::type
621__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000622{
623 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000624 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000625 if (this->__exception_ != nullptr)
626 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000627 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000628}
629
Howard Hinnant99968442011-11-29 18:15:50 +0000630template <class _Rp>
631class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000632 : public __assoc_sub_state
633{
634 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000635 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000636protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000637 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000638
Howard Hinnant1694d232011-05-28 14:41:13 +0000639 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000640public:
641
Howard Hinnant99968442011-11-29 18:15:50 +0000642 void set_value(_Rp& __arg);
643 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000644
Howard Hinnant99968442011-11-29 18:15:50 +0000645 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000646};
647
Howard Hinnant99968442011-11-29 18:15:50 +0000648template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000649void
Howard Hinnant99968442011-11-29 18:15:50 +0000650__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000651{
652 delete this;
653}
654
Howard Hinnant99968442011-11-29 18:15:50 +0000655template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000656void
Howard Hinnant99968442011-11-29 18:15:50 +0000657__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000658{
659 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000660#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000661 if (this->__has_value())
662 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000663#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000664 __value_ = &__arg;
665 this->__state_ |= base::__constructed | base::ready;
666 __lk.unlock();
667 __cv_.notify_all();
668}
669
Howard Hinnant99968442011-11-29 18:15:50 +0000670template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000671void
Howard Hinnant99968442011-11-29 18:15:50 +0000672__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000673{
674 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000675#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000676 if (this->__has_value())
677 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000678#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000679 __value_ = &__arg;
680 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000681 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000682 __lk.unlock();
683}
684
Howard Hinnant99968442011-11-29 18:15:50 +0000685template <class _Rp>
686_Rp&
687__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000688{
689 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000690 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000691 if (this->__exception_ != nullptr)
692 rethrow_exception(this->__exception_);
693 return *__value_;
694}
695
Howard Hinnant99968442011-11-29 18:15:50 +0000696template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000697class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000698 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000699{
Howard Hinnant99968442011-11-29 18:15:50 +0000700 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000701 _Alloc __alloc_;
702
Howard Hinnant1694d232011-05-28 14:41:13 +0000703 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000704public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000705 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000706 explicit __assoc_state_alloc(const _Alloc& __a)
707 : __alloc_(__a) {}
708};
709
Howard Hinnant99968442011-11-29 18:15:50 +0000710template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000711void
Howard Hinnant99968442011-11-29 18:15:50 +0000712__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000713{
714 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000715 reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000716 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
717 this->~__assoc_state_alloc();
718 __a.deallocate(this, 1);
719}
720
Howard Hinnant99968442011-11-29 18:15:50 +0000721template <class _Rp, class _Alloc>
722class __assoc_state_alloc<_Rp&, _Alloc>
723 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000724{
Howard Hinnant99968442011-11-29 18:15:50 +0000725 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000726 _Alloc __alloc_;
727
Howard Hinnant1694d232011-05-28 14:41:13 +0000728 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000729public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000730 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000731 explicit __assoc_state_alloc(const _Alloc& __a)
732 : __alloc_(__a) {}
733};
734
Howard Hinnant99968442011-11-29 18:15:50 +0000735template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000736void
Howard Hinnant99968442011-11-29 18:15:50 +0000737__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000738{
739 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
740 this->~__assoc_state_alloc();
741 __a.deallocate(this, 1);
742}
743
Howard Hinnant47499b12010-08-27 20:10:19 +0000744template <class _Alloc>
745class __assoc_sub_state_alloc
746 : public __assoc_sub_state
747{
748 typedef __assoc_sub_state base;
749 _Alloc __alloc_;
750
Howard Hinnant1694d232011-05-28 14:41:13 +0000751 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000752public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000753 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000754 explicit __assoc_sub_state_alloc(const _Alloc& __a)
755 : __alloc_(__a) {}
756};
757
758template <class _Alloc>
759void
Howard Hinnant1694d232011-05-28 14:41:13 +0000760__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000761{
Howard Hinnantf39daa82010-08-28 21:01:06 +0000762 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000763 this->~__assoc_sub_state_alloc();
764 __a.deallocate(this, 1);
765}
766
Howard Hinnant99968442011-11-29 18:15:50 +0000767template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000768class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000769 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000770{
Howard Hinnant99968442011-11-29 18:15:50 +0000771 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000772
Howard Hinnant99968442011-11-29 18:15:50 +0000773 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000774
775public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000776#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000777 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000778#endif
779
780 virtual void __execute();
781};
782
Howard Hinnant73d21a42010-09-04 23:28:19 +0000783#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000784
Howard Hinnant99968442011-11-29 18:15:50 +0000785template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000786inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000787__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
788 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000789{
790 this->__set_deferred();
791}
792
Howard Hinnant73d21a42010-09-04 23:28:19 +0000793#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000794
Howard Hinnant99968442011-11-29 18:15:50 +0000795template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000796void
Howard Hinnant99968442011-11-29 18:15:50 +0000797__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000798{
799#ifndef _LIBCPP_NO_EXCEPTIONS
800 try
801 {
802#endif // _LIBCPP_NO_EXCEPTIONS
803 this->set_value(__func_());
804#ifndef _LIBCPP_NO_EXCEPTIONS
805 }
806 catch (...)
807 {
808 this->set_exception(current_exception());
809 }
810#endif // _LIBCPP_NO_EXCEPTIONS
811}
812
Howard Hinnant99968442011-11-29 18:15:50 +0000813template <class _Fp>
814class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000815 : public __assoc_sub_state
816{
817 typedef __assoc_sub_state base;
818
Howard Hinnant99968442011-11-29 18:15:50 +0000819 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000820
821public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000822#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000823 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000824#endif
825
826 virtual void __execute();
827};
828
Howard Hinnant73d21a42010-09-04 23:28:19 +0000829#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000830
Howard Hinnant99968442011-11-29 18:15:50 +0000831template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000832inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000833__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
834 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000835{
836 this->__set_deferred();
837}
838
Howard Hinnant73d21a42010-09-04 23:28:19 +0000839#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000840
Howard Hinnant99968442011-11-29 18:15:50 +0000841template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000842void
Howard Hinnant99968442011-11-29 18:15:50 +0000843__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000844{
845#ifndef _LIBCPP_NO_EXCEPTIONS
846 try
847 {
848#endif // _LIBCPP_NO_EXCEPTIONS
849 __func_();
850 this->set_value();
851#ifndef _LIBCPP_NO_EXCEPTIONS
852 }
853 catch (...)
854 {
855 this->set_exception(current_exception());
856 }
857#endif // _LIBCPP_NO_EXCEPTIONS
858}
859
Howard Hinnant99968442011-11-29 18:15:50 +0000860template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000861class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000862 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000863{
Howard Hinnant99968442011-11-29 18:15:50 +0000864 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000865
Howard Hinnant99968442011-11-29 18:15:50 +0000866 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000867
Howard Hinnant1694d232011-05-28 14:41:13 +0000868 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000869public:
870#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000871 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000872#endif
873
874 virtual void __execute();
875};
876
877#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
878
Howard Hinnant99968442011-11-29 18:15:50 +0000879template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000880inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000881__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
882 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000883{
884}
885
886#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
887
Howard Hinnant99968442011-11-29 18:15:50 +0000888template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000889void
Howard Hinnant99968442011-11-29 18:15:50 +0000890__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000891{
892#ifndef _LIBCPP_NO_EXCEPTIONS
893 try
894 {
895#endif // _LIBCPP_NO_EXCEPTIONS
896 this->set_value(__func_());
897#ifndef _LIBCPP_NO_EXCEPTIONS
898 }
899 catch (...)
900 {
901 this->set_exception(current_exception());
902 }
903#endif // _LIBCPP_NO_EXCEPTIONS
904}
905
Howard Hinnant99968442011-11-29 18:15:50 +0000906template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000907void
Howard Hinnant99968442011-11-29 18:15:50 +0000908__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000909{
910 this->wait();
911 base::__on_zero_shared();
912}
913
Howard Hinnant99968442011-11-29 18:15:50 +0000914template <class _Fp>
915class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000916 : public __assoc_sub_state
917{
918 typedef __assoc_sub_state base;
919
Howard Hinnant99968442011-11-29 18:15:50 +0000920 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000921
Howard Hinnant1694d232011-05-28 14:41:13 +0000922 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000923public:
924#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000925 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000926#endif
927
928 virtual void __execute();
929};
930
931#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
932
Howard Hinnant99968442011-11-29 18:15:50 +0000933template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000934inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000935__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
936 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000937{
938}
939
940#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
941
Howard Hinnant99968442011-11-29 18:15:50 +0000942template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000943void
Howard Hinnant99968442011-11-29 18:15:50 +0000944__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000945{
946#ifndef _LIBCPP_NO_EXCEPTIONS
947 try
948 {
949#endif // _LIBCPP_NO_EXCEPTIONS
950 __func_();
951 this->set_value();
952#ifndef _LIBCPP_NO_EXCEPTIONS
953 }
954 catch (...)
955 {
956 this->set_exception(current_exception());
957 }
958#endif // _LIBCPP_NO_EXCEPTIONS
959}
960
Howard Hinnant99968442011-11-29 18:15:50 +0000961template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000962void
Howard Hinnant99968442011-11-29 18:15:50 +0000963__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000964{
965 this->wait();
966 base::__on_zero_shared();
967}
968
Howard Hinnant83eade62013-03-06 23:30:19 +0000969template <class _Rp> class _LIBCPP_TYPE_VIS promise;
970template <class _Rp> class _LIBCPP_TYPE_VIS shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +0000971
972// future
973
Howard Hinnant83eade62013-03-06 23:30:19 +0000974template <class _Rp> class _LIBCPP_TYPE_VIS future;
Howard Hinnant54da3382010-08-30 18:46:21 +0000975
Howard Hinnant99968442011-11-29 18:15:50 +0000976template <class _Rp, class _Fp>
977future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000978#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000979__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000980#else
Howard Hinnant99968442011-11-29 18:15:50 +0000981__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000982#endif
983
Howard Hinnant99968442011-11-29 18:15:50 +0000984template <class _Rp, class _Fp>
985future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000986#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000987__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000988#else
Howard Hinnant99968442011-11-29 18:15:50 +0000989__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000990#endif
991
Howard Hinnant99968442011-11-29 18:15:50 +0000992template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +0000993class _LIBCPP_TYPE_VIS future
Howard Hinnant47499b12010-08-27 20:10:19 +0000994{
Howard Hinnant99968442011-11-29 18:15:50 +0000995 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000996
Howard Hinnant99968442011-11-29 18:15:50 +0000997 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +0000998
999 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001000 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001001
Howard Hinnant73d21a42010-09-04 23:28:19 +00001002#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001003 template <class _R1, class _Fp>
1004 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1005 template <class _R1, class _Fp>
1006 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001007#else
Howard Hinnant99968442011-11-29 18:15:50 +00001008 template <class _R1, class _Fp>
1009 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1010 template <class _R1, class _Fp>
1011 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001012#endif
1013
Howard Hinnant47499b12010-08-27 20:10:19 +00001014public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001015 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001016 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001017#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001018 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001019 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001020 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1021 future(const future&) = delete;
1022 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001023 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001024 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001025 {
1026 future(std::move(__rhs)).swap(*this);
1027 return *this;
1028 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001029#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001030private:
1031 future(const future&);
1032 future& operator=(const future&);
1033public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001034#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001035 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001036 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001037
1038 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001039 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001040
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001041 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001042 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001043
1044 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001045 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001046 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001047
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001049 void wait() const {__state_->wait();}
1050 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001052 future_status
1053 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1054 {return __state_->wait_for(__rel_time);}
1055 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001057 future_status
1058 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1059 {return __state_->wait_until(__abs_time);}
1060};
1061
Howard Hinnant99968442011-11-29 18:15:50 +00001062template <class _Rp>
1063future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001064 : __state_(__state)
1065{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001066#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001067 if (__state_->__has_future_attached())
1068 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001069#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001070 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001071 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001072}
1073
Howard Hinnant54da3382010-08-30 18:46:21 +00001074struct __release_shared_count
1075{
1076 void operator()(__shared_count* p) {p->__release_shared();}
1077};
1078
Howard Hinnant99968442011-11-29 18:15:50 +00001079template <class _Rp>
1080future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001081{
1082 if (__state_)
1083 __state_->__release_shared();
1084}
1085
Howard Hinnant99968442011-11-29 18:15:50 +00001086template <class _Rp>
1087_Rp
1088future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001089{
Howard Hinnant54da3382010-08-30 18:46:21 +00001090 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001091 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001092 __state_ = nullptr;
1093 return __s->move();
1094}
1095
Howard Hinnant99968442011-11-29 18:15:50 +00001096template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00001097class _LIBCPP_TYPE_VIS future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001098{
Howard Hinnant99968442011-11-29 18:15:50 +00001099 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001100
Howard Hinnant99968442011-11-29 18:15:50 +00001101 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001102
1103 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001104 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001105
Howard Hinnant73d21a42010-09-04 23:28:19 +00001106#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001107 template <class _R1, class _Fp>
1108 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1109 template <class _R1, class _Fp>
1110 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001111#else
Howard Hinnant99968442011-11-29 18:15:50 +00001112 template <class _R1, class _Fp>
1113 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1114 template <class _R1, class _Fp>
1115 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001116#endif
1117
Howard Hinnant47499b12010-08-27 20:10:19 +00001118public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001120 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001121#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001122 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001123 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001124 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1125 future(const future&) = delete;
1126 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001127 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001128 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001129 {
1130 future(std::move(__rhs)).swap(*this);
1131 return *this;
1132 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001133#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001134private:
1135 future(const future&);
1136 future& operator=(const future&);
1137public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001138#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001139 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001140 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001141
1142 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001143 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001144
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001145 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001146 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001147
1148 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001149 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001150 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001151
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001152 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001153 void wait() const {__state_->wait();}
1154 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001155 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001156 future_status
1157 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1158 {return __state_->wait_for(__rel_time);}
1159 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001160 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001161 future_status
1162 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1163 {return __state_->wait_until(__abs_time);}
1164};
1165
Howard Hinnant99968442011-11-29 18:15:50 +00001166template <class _Rp>
1167future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001168 : __state_(__state)
1169{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001170#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001171 if (__state_->__has_future_attached())
1172 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001173#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001174 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001175 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001176}
1177
Howard Hinnant99968442011-11-29 18:15:50 +00001178template <class _Rp>
1179future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001180{
1181 if (__state_)
1182 __state_->__release_shared();
1183}
1184
Howard Hinnant99968442011-11-29 18:15:50 +00001185template <class _Rp>
1186_Rp&
1187future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001188{
Howard Hinnant54da3382010-08-30 18:46:21 +00001189 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001190 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001191 __state_ = nullptr;
1192 return __s->copy();
1193}
1194
1195template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001196class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001197{
1198 __assoc_sub_state* __state_;
1199
1200 explicit future(__assoc_sub_state* __state);
1201
1202 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001203 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001204
Howard Hinnant73d21a42010-09-04 23:28:19 +00001205#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001206 template <class _R1, class _Fp>
1207 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1208 template <class _R1, class _Fp>
1209 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001210#else
Howard Hinnant99968442011-11-29 18:15:50 +00001211 template <class _R1, class _Fp>
1212 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1213 template <class _R1, class _Fp>
1214 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001215#endif
1216
Howard Hinnant47499b12010-08-27 20:10:19 +00001217public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001218 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001219 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001220#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001222 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001223 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1224 future(const future&) = delete;
1225 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001226 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001227 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001228 {
1229 future(std::move(__rhs)).swap(*this);
1230 return *this;
1231 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001232#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001233private:
1234 future(const future&);
1235 future& operator=(const future&);
1236public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001237#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001238 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001239 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001240
1241 // retrieving the value
1242 void get();
1243
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001244 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001245 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001246
1247 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001249 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001250
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001252 void wait() const {__state_->wait();}
1253 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001255 future_status
1256 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1257 {return __state_->wait_for(__rel_time);}
1258 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001259 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001260 future_status
1261 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1262 {return __state_->wait_until(__abs_time);}
1263};
1264
Howard Hinnant99968442011-11-29 18:15:50 +00001265template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001266inline _LIBCPP_INLINE_VISIBILITY
1267void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001268swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00001269{
1270 __x.swap(__y);
1271}
1272
Howard Hinnant47499b12010-08-27 20:10:19 +00001273// promise<R>
1274
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001275template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001276
Howard Hinnant99968442011-11-29 18:15:50 +00001277template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00001278class _LIBCPP_TYPE_VIS promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001279{
Howard Hinnant99968442011-11-29 18:15:50 +00001280 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001281
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001282 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001283 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001284
1285 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001286public:
1287 promise();
1288 template <class _Alloc>
1289 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001290#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001291 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001292 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001293 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1294 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001295#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001296private:
1297 promise(const promise& __rhs);
1298public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001299#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001300 ~promise();
1301
1302 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001303#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001305 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001306 {
1307 promise(std::move(__rhs)).swap(*this);
1308 return *this;
1309 }
1310 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001311#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001312private:
1313 promise& operator=(const promise& __rhs);
1314public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001315#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001316 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001317 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001318
1319 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001320 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001321
1322 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001323 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001324#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001325 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001326#endif
1327 void set_exception(exception_ptr __p);
1328
1329 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001330 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001331#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001332 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001333#endif
1334 void set_exception_at_thread_exit(exception_ptr __p);
1335};
1336
Howard Hinnant99968442011-11-29 18:15:50 +00001337template <class _Rp>
1338promise<_Rp>::promise()
1339 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001340{
1341}
1342
Howard Hinnant99968442011-11-29 18:15:50 +00001343template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001344template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001345promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001346{
Howard Hinnant99968442011-11-29 18:15:50 +00001347 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001348 typedef __allocator_destructor<_A2> _D2;
1349 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001350 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1351 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001352 __state_ = __hold.release();
1353}
1354
Howard Hinnant99968442011-11-29 18:15:50 +00001355template <class _Rp>
1356promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001357{
1358 if (__state_)
1359 {
1360 if (!__state_->__has_value() && __state_->use_count() > 1)
1361 __state_->set_exception(make_exception_ptr(
1362 future_error(make_error_code(future_errc::broken_promise))
1363 ));
1364 __state_->__release_shared();
1365 }
1366}
1367
Howard Hinnant99968442011-11-29 18:15:50 +00001368template <class _Rp>
1369future<_Rp>
1370promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001371{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001372#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001373 if (__state_ == nullptr)
1374 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001375#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001376 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001377}
1378
Howard Hinnant99968442011-11-29 18:15:50 +00001379template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001380void
Howard Hinnant99968442011-11-29 18:15:50 +00001381promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001382{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001383#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001384 if (__state_ == nullptr)
1385 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001386#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001387 __state_->set_value(__r);
1388}
1389
Howard Hinnant73d21a42010-09-04 23:28:19 +00001390#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001391
Howard Hinnant99968442011-11-29 18:15:50 +00001392template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001393void
Howard Hinnant99968442011-11-29 18:15:50 +00001394promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001395{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001396#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001397 if (__state_ == nullptr)
1398 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001399#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001400 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001401}
1402
Howard Hinnant73d21a42010-09-04 23:28:19 +00001403#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001404
Howard Hinnant99968442011-11-29 18:15:50 +00001405template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001406void
Howard Hinnant99968442011-11-29 18:15:50 +00001407promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001408{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001409#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001410 if (__state_ == nullptr)
1411 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001412#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001413 __state_->set_exception(__p);
1414}
1415
Howard Hinnant99968442011-11-29 18:15:50 +00001416template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001417void
Howard Hinnant99968442011-11-29 18:15:50 +00001418promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001419{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001420#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001421 if (__state_ == nullptr)
1422 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001423#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001424 __state_->set_value_at_thread_exit(__r);
1425}
1426
Howard Hinnant73d21a42010-09-04 23:28:19 +00001427#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001428
Howard Hinnant99968442011-11-29 18:15:50 +00001429template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001430void
Howard Hinnant99968442011-11-29 18:15:50 +00001431promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001432{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001433#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001434 if (__state_ == nullptr)
1435 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001436#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001437 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001438}
1439
Howard Hinnant73d21a42010-09-04 23:28:19 +00001440#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001441
Howard Hinnant99968442011-11-29 18:15:50 +00001442template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001443void
Howard Hinnant99968442011-11-29 18:15:50 +00001444promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001445{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001446#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001447 if (__state_ == nullptr)
1448 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001449#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001450 __state_->set_exception_at_thread_exit(__p);
1451}
1452
1453// promise<R&>
1454
Howard Hinnant99968442011-11-29 18:15:50 +00001455template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00001456class _LIBCPP_TYPE_VIS promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001457{
Howard Hinnant99968442011-11-29 18:15:50 +00001458 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001459
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001460 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001461 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001462
1463 template <class> friend class packaged_task;
1464
Howard Hinnant47499b12010-08-27 20:10:19 +00001465public:
1466 promise();
1467 template <class _Allocator>
1468 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001469#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001470 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001471 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001472 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1473 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001474#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001475private:
1476 promise(const promise& __rhs);
1477public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001478#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001479 ~promise();
1480
1481 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001482#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001484 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001485 {
1486 promise(std::move(__rhs)).swap(*this);
1487 return *this;
1488 }
1489 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001490#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001491private:
1492 promise& operator=(const promise& __rhs);
1493public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001494#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001495 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001496 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001497
1498 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001499 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001500
1501 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001502 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001503 void set_exception(exception_ptr __p);
1504
1505 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001506 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001507 void set_exception_at_thread_exit(exception_ptr __p);
1508};
1509
Howard Hinnant99968442011-11-29 18:15:50 +00001510template <class _Rp>
1511promise<_Rp&>::promise()
1512 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001513{
1514}
1515
Howard Hinnant99968442011-11-29 18:15:50 +00001516template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001517template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001518promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001519{
Howard Hinnant99968442011-11-29 18:15:50 +00001520 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001521 typedef __allocator_destructor<_A2> _D2;
1522 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001523 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1524 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001525 __state_ = __hold.release();
1526}
1527
Howard Hinnant99968442011-11-29 18:15:50 +00001528template <class _Rp>
1529promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001530{
1531 if (__state_)
1532 {
1533 if (!__state_->__has_value() && __state_->use_count() > 1)
1534 __state_->set_exception(make_exception_ptr(
1535 future_error(make_error_code(future_errc::broken_promise))
1536 ));
1537 __state_->__release_shared();
1538 }
1539}
1540
Howard Hinnant99968442011-11-29 18:15:50 +00001541template <class _Rp>
1542future<_Rp&>
1543promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001544{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001545#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001546 if (__state_ == nullptr)
1547 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001548#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001549 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001550}
1551
Howard Hinnant99968442011-11-29 18:15:50 +00001552template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001553void
Howard Hinnant99968442011-11-29 18:15:50 +00001554promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001555{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001556#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001557 if (__state_ == nullptr)
1558 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001559#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001560 __state_->set_value(__r);
1561}
1562
Howard Hinnant99968442011-11-29 18:15:50 +00001563template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001564void
Howard Hinnant99968442011-11-29 18:15:50 +00001565promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001566{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001567#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001568 if (__state_ == nullptr)
1569 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001570#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001571 __state_->set_exception(__p);
1572}
1573
Howard Hinnant99968442011-11-29 18:15:50 +00001574template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001575void
Howard Hinnant99968442011-11-29 18:15:50 +00001576promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001577{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001578#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001579 if (__state_ == nullptr)
1580 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001581#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001582 __state_->set_value_at_thread_exit(__r);
1583}
1584
Howard Hinnant99968442011-11-29 18:15:50 +00001585template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001586void
Howard Hinnant99968442011-11-29 18:15:50 +00001587promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001588{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001589#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001590 if (__state_ == nullptr)
1591 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001592#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001593 __state_->set_exception_at_thread_exit(__p);
1594}
1595
1596// promise<void>
1597
1598template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001599class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001600{
1601 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001602
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001604 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001605
1606 template <class> friend class packaged_task;
1607
Howard Hinnant47499b12010-08-27 20:10:19 +00001608public:
1609 promise();
1610 template <class _Allocator>
1611 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001612#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001613 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001614 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001615 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1616 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001617#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001618private:
1619 promise(const promise& __rhs);
1620public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001621#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001622 ~promise();
1623
1624 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001625#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001626 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001627 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001628 {
1629 promise(std::move(__rhs)).swap(*this);
1630 return *this;
1631 }
1632 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001633#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001634private:
1635 promise& operator=(const promise& __rhs);
1636public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001637#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001638 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001639 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001640
1641 // retrieving the result
1642 future<void> get_future();
1643
1644 // setting the result
1645 void set_value();
1646 void set_exception(exception_ptr __p);
1647
1648 // setting the result with deferred notification
1649 void set_value_at_thread_exit();
1650 void set_exception_at_thread_exit(exception_ptr __p);
1651};
1652
1653template <class _Alloc>
1654promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1655{
1656 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1657 typedef __allocator_destructor<_A2> _D2;
1658 _A2 __a(__a0);
1659 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1660 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1661 __state_ = __hold.release();
1662}
1663
Howard Hinnant99968442011-11-29 18:15:50 +00001664template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001665inline _LIBCPP_INLINE_VISIBILITY
1666void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001667swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001668{
1669 __x.swap(__y);
1670}
1671
Howard Hinnant99968442011-11-29 18:15:50 +00001672template <class _Rp, class _Alloc>
Howard Hinnant83eade62013-03-06 23:30:19 +00001673 struct _LIBCPP_TYPE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001674 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001675
Howard Hinnant54da3382010-08-30 18:46:21 +00001676#ifndef _LIBCPP_HAS_NO_VARIADICS
1677
1678// packaged_task
1679
1680template<class _Fp> class __packaged_task_base;
1681
Howard Hinnant99968442011-11-29 18:15:50 +00001682template<class _Rp, class ..._ArgTypes>
1683class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001684{
1685 __packaged_task_base(const __packaged_task_base&);
1686 __packaged_task_base& operator=(const __packaged_task_base&);
1687public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001688 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001689 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001690 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001691 virtual ~__packaged_task_base() {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001692 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001693 virtual void destroy() = 0;
1694 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001695 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001696};
1697
1698template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1699
Howard Hinnant99968442011-11-29 18:15:50 +00001700template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1701class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1702 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001703{
Howard Hinnant99968442011-11-29 18:15:50 +00001704 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001705public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001707 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001709 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001711 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001712 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001713 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001714 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001715 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001716 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001717 virtual void destroy();
1718 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001719 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001720};
1721
Howard Hinnant99968442011-11-29 18:15:50 +00001722template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001723void
Howard Hinnant99968442011-11-29 18:15:50 +00001724__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001725 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001726{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001727 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001728}
1729
Howard Hinnant99968442011-11-29 18:15:50 +00001730template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001731void
Howard Hinnant99968442011-11-29 18:15:50 +00001732__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001733{
Howard Hinnant99968442011-11-29 18:15:50 +00001734 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001735}
1736
Howard Hinnant99968442011-11-29 18:15:50 +00001737template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001738void
Howard Hinnant99968442011-11-29 18:15:50 +00001739__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001740{
Howard Hinnant99968442011-11-29 18:15:50 +00001741 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1742 _Ap __a(__f_.second());
1743 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001744 __a.deallocate(this, 1);
1745}
1746
Howard Hinnant99968442011-11-29 18:15:50 +00001747template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1748_Rp
1749__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001750{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001751 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001752}
1753
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001754template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001755
Howard Hinnant99968442011-11-29 18:15:50 +00001756template<class _Rp, class ..._ArgTypes>
1757class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001758{
Howard Hinnant99968442011-11-29 18:15:50 +00001759 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant78f0de22013-01-21 17:26:55 +00001760 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001761 __base* __f_;
1762
1763public:
Howard Hinnant99968442011-11-29 18:15:50 +00001764 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001765
1766 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001767 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001768 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001769 template<class _Fp>
1770 __packaged_task_function(_Fp&& __f);
1771 template<class _Fp, class _Alloc>
1772 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001773
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001774 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1775 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001776
1777 __packaged_task_function(const __packaged_task_function&) = delete;
1778 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1779
1780 ~__packaged_task_function();
1781
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001782 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001783
Howard Hinnant99968442011-11-29 18:15:50 +00001784 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001785};
1786
Howard Hinnant99968442011-11-29 18:15:50 +00001787template<class _Rp, class ..._ArgTypes>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001788__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001789{
1790 if (__f.__f_ == nullptr)
1791 __f_ = nullptr;
1792 else if (__f.__f_ == (__base*)&__f.__buf_)
1793 {
1794 __f_ = (__base*)&__buf_;
1795 __f.__f_->__move_to(__f_);
1796 }
1797 else
1798 {
1799 __f_ = __f.__f_;
1800 __f.__f_ = nullptr;
1801 }
1802}
1803
Howard Hinnant99968442011-11-29 18:15:50 +00001804template<class _Rp, class ..._ArgTypes>
1805template <class _Fp>
1806__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001807 : __f_(nullptr)
1808{
Howard Hinnant99968442011-11-29 18:15:50 +00001809 typedef typename remove_reference<_Fp>::type _FR;
1810 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001811 if (sizeof(_FF) <= sizeof(__buf_))
1812 {
1813 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001814 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001815 }
1816 else
1817 {
Howard Hinnant99968442011-11-29 18:15:50 +00001818 typedef allocator<_FF> _Ap;
1819 _Ap __a;
1820 typedef __allocator_destructor<_Ap> _Dp;
1821 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1822 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001823 __f_ = __hold.release();
1824 }
1825}
1826
Howard Hinnant99968442011-11-29 18:15:50 +00001827template<class _Rp, class ..._ArgTypes>
1828template <class _Fp, class _Alloc>
1829__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1830 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001831 : __f_(nullptr)
1832{
1833 typedef allocator_traits<_Alloc> __alloc_traits;
Howard Hinnant99968442011-11-29 18:15:50 +00001834 typedef typename remove_reference<_Fp>::type _FR;
1835 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001836 if (sizeof(_FF) <= sizeof(__buf_))
1837 {
1838 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001839 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001840 }
1841 else
1842 {
1843 typedef typename __alloc_traits::template
1844#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1845 rebind_alloc<_FF>
1846#else
1847 rebind_alloc<_FF>::other
1848#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001849 _Ap;
1850 _Ap __a(__a0);
1851 typedef __allocator_destructor<_Ap> _Dp;
1852 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1853 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001854 __f_ = __hold.release();
1855 }
1856}
1857
Howard Hinnant99968442011-11-29 18:15:50 +00001858template<class _Rp, class ..._ArgTypes>
1859__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001860__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001861{
1862 if (__f_ == (__base*)&__buf_)
1863 __f_->destroy();
1864 else if (__f_)
1865 __f_->destroy_deallocate();
1866 __f_ = nullptr;
1867 if (__f.__f_ == nullptr)
1868 __f_ = nullptr;
1869 else if (__f.__f_ == (__base*)&__f.__buf_)
1870 {
1871 __f_ = (__base*)&__buf_;
1872 __f.__f_->__move_to(__f_);
1873 }
1874 else
1875 {
1876 __f_ = __f.__f_;
1877 __f.__f_ = nullptr;
1878 }
Argyrios Kyrtzidis1dc6f7a2012-10-13 02:03:45 +00001879 return *this;
Howard Hinnant54da3382010-08-30 18:46:21 +00001880}
1881
Howard Hinnant99968442011-11-29 18:15:50 +00001882template<class _Rp, class ..._ArgTypes>
1883__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001884{
1885 if (__f_ == (__base*)&__buf_)
1886 __f_->destroy();
1887 else if (__f_)
1888 __f_->destroy_deallocate();
1889}
1890
Howard Hinnant99968442011-11-29 18:15:50 +00001891template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001892void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001893__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001894{
1895 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1896 {
1897 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1898 __base* __t = (__base*)&__tempbuf;
1899 __f_->__move_to(__t);
1900 __f_->destroy();
1901 __f_ = nullptr;
1902 __f.__f_->__move_to((__base*)&__buf_);
1903 __f.__f_->destroy();
1904 __f.__f_ = nullptr;
1905 __f_ = (__base*)&__buf_;
1906 __t->__move_to((__base*)&__f.__buf_);
1907 __t->destroy();
1908 __f.__f_ = (__base*)&__f.__buf_;
1909 }
1910 else if (__f_ == (__base*)&__buf_)
1911 {
1912 __f_->__move_to((__base*)&__f.__buf_);
1913 __f_->destroy();
1914 __f_ = __f.__f_;
1915 __f.__f_ = (__base*)&__f.__buf_;
1916 }
1917 else if (__f.__f_ == (__base*)&__f.__buf_)
1918 {
1919 __f.__f_->__move_to((__base*)&__buf_);
1920 __f.__f_->destroy();
1921 __f.__f_ = __f_;
1922 __f_ = (__base*)&__buf_;
1923 }
1924 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001925 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001926}
1927
Howard Hinnant99968442011-11-29 18:15:50 +00001928template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001929inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001930_Rp
1931__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00001932{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001933 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001934}
1935
Howard Hinnant99968442011-11-29 18:15:50 +00001936template<class _Rp, class ..._ArgTypes>
Howard Hinnant83eade62013-03-06 23:30:19 +00001937class _LIBCPP_TYPE_VIS packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001938{
1939public:
Howard Hinnant99968442011-11-29 18:15:50 +00001940 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001941
1942private:
1943 __packaged_task_function<result_type(_ArgTypes...)> __f_;
1944 promise<result_type> __p_;
1945
1946public:
1947 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001948 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001949 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001950 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001951 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001952 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
1953 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001954 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001955 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
1956 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00001957 __p_(allocator_arg, __a) {}
1958 // ~packaged_task() = default;
1959
1960 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00001961 packaged_task(const packaged_task&) = delete;
1962 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00001963
1964 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001965 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001966 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00001967 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001968 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001969 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001970 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00001971 __f_ = _VSTD::move(__other.__f_);
1972 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001973 return *this;
1974 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001975 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001976 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001977 {
1978 __f_.swap(__other.__f_);
1979 __p_.swap(__other.__p_);
1980 }
1981
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001982 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001983 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00001984
1985 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001986 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001987 future<result_type> get_future() {return __p_.get_future();}
1988
1989 // execution
1990 void operator()(_ArgTypes... __args);
1991 void make_ready_at_thread_exit(_ArgTypes... __args);
1992
1993 void reset();
1994};
1995
Howard Hinnant99968442011-11-29 18:15:50 +00001996template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001997void
Howard Hinnant99968442011-11-29 18:15:50 +00001998packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00001999{
2000#ifndef _LIBCPP_NO_EXCEPTIONS
2001 if (__p_.__state_ == nullptr)
2002 throw future_error(make_error_code(future_errc::no_state));
2003 if (__p_.__state_->__has_value())
2004 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2005 try
2006 {
2007#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002008 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002009#ifndef _LIBCPP_NO_EXCEPTIONS
2010 }
2011 catch (...)
2012 {
2013 __p_.set_exception(current_exception());
2014 }
2015#endif // _LIBCPP_NO_EXCEPTIONS
2016}
2017
Howard Hinnant99968442011-11-29 18:15:50 +00002018template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002019void
Howard Hinnant99968442011-11-29 18:15:50 +00002020packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002021{
2022#ifndef _LIBCPP_NO_EXCEPTIONS
2023 if (__p_.__state_ == nullptr)
2024 throw future_error(make_error_code(future_errc::no_state));
2025 if (__p_.__state_->__has_value())
2026 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2027 try
2028 {
2029#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002030 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002031#ifndef _LIBCPP_NO_EXCEPTIONS
2032 }
2033 catch (...)
2034 {
2035 __p_.set_exception_at_thread_exit(current_exception());
2036 }
2037#endif // _LIBCPP_NO_EXCEPTIONS
2038}
2039
Howard Hinnant99968442011-11-29 18:15:50 +00002040template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002041void
Howard Hinnant99968442011-11-29 18:15:50 +00002042packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002043{
2044#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002045 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002046 throw future_error(make_error_code(future_errc::no_state));
2047#endif // _LIBCPP_NO_EXCEPTIONS
2048 __p_ = promise<result_type>();
2049}
2050
2051template<class ..._ArgTypes>
Howard Hinnant83eade62013-03-06 23:30:19 +00002052class _LIBCPP_TYPE_VIS packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002053{
2054public:
2055 typedef void result_type;
2056
2057private:
2058 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2059 promise<result_type> __p_;
2060
2061public:
2062 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002063 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002064 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00002065 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002067 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2068 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002070 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2071 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002072 __p_(allocator_arg, __a) {}
2073 // ~packaged_task() = default;
2074
2075 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002076 packaged_task(const packaged_task&) = delete;
2077 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002078
2079 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002080 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002081 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002082 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002083 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002084 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002085 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002086 __f_ = _VSTD::move(__other.__f_);
2087 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002088 return *this;
2089 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002090 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002091 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002092 {
2093 __f_.swap(__other.__f_);
2094 __p_.swap(__other.__p_);
2095 }
2096
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002098 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002099
2100 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002101 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002102 future<result_type> get_future() {return __p_.get_future();}
2103
2104 // execution
2105 void operator()(_ArgTypes... __args);
2106 void make_ready_at_thread_exit(_ArgTypes... __args);
2107
2108 void reset();
2109};
2110
2111template<class ..._ArgTypes>
2112void
2113packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2114{
2115#ifndef _LIBCPP_NO_EXCEPTIONS
2116 if (__p_.__state_ == nullptr)
2117 throw future_error(make_error_code(future_errc::no_state));
2118 if (__p_.__state_->__has_value())
2119 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2120 try
2121 {
2122#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002123 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002124 __p_.set_value();
2125#ifndef _LIBCPP_NO_EXCEPTIONS
2126 }
2127 catch (...)
2128 {
2129 __p_.set_exception(current_exception());
2130 }
2131#endif // _LIBCPP_NO_EXCEPTIONS
2132}
2133
2134template<class ..._ArgTypes>
2135void
2136packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2137{
2138#ifndef _LIBCPP_NO_EXCEPTIONS
2139 if (__p_.__state_ == nullptr)
2140 throw future_error(make_error_code(future_errc::no_state));
2141 if (__p_.__state_->__has_value())
2142 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2143 try
2144 {
2145#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002146 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002147 __p_.set_value_at_thread_exit();
2148#ifndef _LIBCPP_NO_EXCEPTIONS
2149 }
2150 catch (...)
2151 {
2152 __p_.set_exception_at_thread_exit(current_exception());
2153 }
2154#endif // _LIBCPP_NO_EXCEPTIONS
2155}
2156
2157template<class ..._ArgTypes>
2158void
2159packaged_task<void(_ArgTypes...)>::reset()
2160{
2161#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002162 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002163 throw future_error(make_error_code(future_errc::no_state));
2164#endif // _LIBCPP_NO_EXCEPTIONS
2165 __p_ = promise<result_type>();
2166}
2167
2168template <class _Callable>
2169inline _LIBCPP_INLINE_VISIBILITY
2170void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002171swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002172{
2173 __x.swap(__y);
2174}
2175
2176template <class _Callable, class _Alloc>
Howard Hinnant83eade62013-03-06 23:30:19 +00002177struct _LIBCPP_TYPE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002178 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002179
Howard Hinnant99968442011-11-29 18:15:50 +00002180template <class _Rp, class _Fp>
2181future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002182#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002183__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002184#else
Howard Hinnant99968442011-11-29 18:15:50 +00002185__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002186#endif
2187{
Howard Hinnant99968442011-11-29 18:15:50 +00002188 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2189 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2190 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002191}
2192
Howard Hinnant99968442011-11-29 18:15:50 +00002193template <class _Rp, class _Fp>
2194future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002195#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002196__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002197#else
Howard Hinnant99968442011-11-29 18:15:50 +00002198__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002199#endif
2200{
Howard Hinnant99968442011-11-29 18:15:50 +00002201 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2202 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2203 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2204 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002205}
2206
Howard Hinnant99968442011-11-29 18:15:50 +00002207template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002208class __async_func
2209{
Howard Hinnant99968442011-11-29 18:15:50 +00002210 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002211
2212public:
Howard Hinnant99968442011-11-29 18:15:50 +00002213 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002214
2215 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002216 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002217 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002218
2219 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002220 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002221
Howard Hinnant99968442011-11-29 18:15:50 +00002222 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002223 {
2224 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2225 return __execute(_Index());
2226 }
2227private:
2228 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002229 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002230 __execute(__tuple_indices<_Indices...>)
2231 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002232 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002233 }
2234};
2235
Howard Hinnant99968442011-11-29 18:15:50 +00002236template <class _Fp, class... _Args>
2237future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2238async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002239{
Howard Hinnant99968442011-11-29 18:15:50 +00002240 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2241 typedef typename _BF::_Rp _Rp;
2242 future<_Rp> __r;
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002243 if (int(__policy) & int(launch::async))
Howard Hinnant99968442011-11-29 18:15:50 +00002244 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002245 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002246 else if (int(__policy) & int(launch::deferred))
Howard Hinnant99968442011-11-29 18:15:50 +00002247 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002248 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002249 return __r;
2250}
2251
Howard Hinnant99968442011-11-29 18:15:50 +00002252template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002253inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002254future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2255async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002256{
Howard Hinnant99968442011-11-29 18:15:50 +00002257 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002258 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002259}
2260
2261#endif // _LIBCPP_HAS_NO_VARIADICS
2262
Howard Hinnante6e4d012010-09-03 21:46:37 +00002263// shared_future
2264
Howard Hinnant99968442011-11-29 18:15:50 +00002265template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00002266class _LIBCPP_TYPE_VIS shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002267{
Howard Hinnant99968442011-11-29 18:15:50 +00002268 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002269
2270public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002271 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002272 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002273 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002274 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2275 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002276#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002277 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002278 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002279 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002280 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002281 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002282 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002283#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002284 ~shared_future();
2285 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002286#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002287 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002288 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002289 {
2290 shared_future(std::move(__rhs)).swap(*this);
2291 return *this;
2292 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002293#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002294
2295 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002296 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002297 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002298
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002300 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002301
2302 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002303 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002304 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002305
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002306 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002307 void wait() const {__state_->wait();}
2308 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002310 future_status
2311 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2312 {return __state_->wait_for(__rel_time);}
2313 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002315 future_status
2316 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2317 {return __state_->wait_until(__abs_time);}
2318};
2319
Howard Hinnant99968442011-11-29 18:15:50 +00002320template <class _Rp>
2321shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002322{
2323 if (__state_)
2324 __state_->__release_shared();
2325}
2326
Howard Hinnant99968442011-11-29 18:15:50 +00002327template <class _Rp>
2328shared_future<_Rp>&
2329shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002330{
2331 if (__rhs.__state_)
2332 __rhs.__state_->__add_shared();
2333 if (__state_)
2334 __state_->__release_shared();
2335 __state_ = __rhs.__state_;
2336 return *this;
2337}
2338
Howard Hinnant99968442011-11-29 18:15:50 +00002339template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00002340class _LIBCPP_TYPE_VIS shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002341{
Howard Hinnant99968442011-11-29 18:15:50 +00002342 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002343
2344public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002345 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002346 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002347 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002348 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2349 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002350#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002351 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002352 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002353 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002354 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002355 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002356 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002357#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002358 ~shared_future();
2359 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002360#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002361 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002362 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002363 {
2364 shared_future(std::move(__rhs)).swap(*this);
2365 return *this;
2366 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002367#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002368
2369 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002371 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002372
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002373 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002374 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002375
2376 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002377 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002378 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002379
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002381 void wait() const {__state_->wait();}
2382 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002384 future_status
2385 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2386 {return __state_->wait_for(__rel_time);}
2387 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002389 future_status
2390 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2391 {return __state_->wait_until(__abs_time);}
2392};
2393
Howard Hinnant99968442011-11-29 18:15:50 +00002394template <class _Rp>
2395shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002396{
2397 if (__state_)
2398 __state_->__release_shared();
2399}
2400
Howard Hinnant99968442011-11-29 18:15:50 +00002401template <class _Rp>
2402shared_future<_Rp&>&
2403shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002404{
2405 if (__rhs.__state_)
2406 __rhs.__state_->__add_shared();
2407 if (__state_)
2408 __state_->__release_shared();
2409 __state_ = __rhs.__state_;
2410 return *this;
2411}
2412
2413template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00002414class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002415{
2416 __assoc_sub_state* __state_;
2417
2418public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002419 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002420 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002422 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2423 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002424#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002425 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002426 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002427 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002428 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002429 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002430 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002431#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002432 ~shared_future();
2433 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002434#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002436 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002437 {
2438 shared_future(std::move(__rhs)).swap(*this);
2439 return *this;
2440 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002441#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002442
2443 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002444 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002445 void get() const {__state_->copy();}
2446
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002448 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002449
2450 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002451 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002452 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002453
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002454 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002455 void wait() const {__state_->wait();}
2456 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002458 future_status
2459 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2460 {return __state_->wait_for(__rel_time);}
2461 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002462 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002463 future_status
2464 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2465 {return __state_->wait_until(__abs_time);}
2466};
2467
Howard Hinnant99968442011-11-29 18:15:50 +00002468template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002469inline _LIBCPP_INLINE_VISIBILITY
2470void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002471swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002472{
2473 __x.swap(__y);
2474}
2475
Howard Hinnant99968442011-11-29 18:15:50 +00002476template <class _Rp>
Howard Hinnant7de47902010-11-30 20:23:32 +00002477inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002478shared_future<_Rp>
2479future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002480{
Howard Hinnant99968442011-11-29 18:15:50 +00002481 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002482}
2483
Howard Hinnant99968442011-11-29 18:15:50 +00002484template <class _Rp>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002485inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002486shared_future<_Rp&>
2487future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002488{
Howard Hinnant99968442011-11-29 18:15:50 +00002489 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002490}
2491
Howard Hinnanta4451512010-12-02 16:45:21 +00002492#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2493
Howard Hinnant7de47902010-11-30 20:23:32 +00002494inline _LIBCPP_INLINE_VISIBILITY
2495shared_future<void>
2496future<void>::share()
2497{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002498 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002499}
2500
Howard Hinnanta4451512010-12-02 16:45:21 +00002501#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2502
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002503_LIBCPP_END_NAMESPACE_STD
2504
2505#endif // _LIBCPP_FUTURE