blob: dae1a4b805ec69581fb81b9d909d5ec496a74618 [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
Howard Hinnantf491e512013-06-29 18:38:17 +0000406#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
407
408#ifdef _LIBCXX_UNDERLYING_TYPE
409typedef underlying_type<launch>::type __launch_underlying_type;
410#else
411typedef int __launch_underlying_type;
412#endif
413
414inline _LIBCPP_INLINE_VISIBILITY
415_LIBCPP_CONSTEXPR
416launch
417operator&(launch __x, launch __y)
418{
419 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
420 static_cast<__launch_underlying_type>(__y));
421}
422
423inline _LIBCPP_INLINE_VISIBILITY
424_LIBCPP_CONSTEXPR
425launch
426operator|(launch __x, launch __y)
427{
428 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
429 static_cast<__launch_underlying_type>(__y));
430}
431
432inline _LIBCPP_INLINE_VISIBILITY
433_LIBCPP_CONSTEXPR
434launch
435operator^(launch __x, launch __y)
436{
437 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
438 static_cast<__launch_underlying_type>(__y));
439}
440
441inline _LIBCPP_INLINE_VISIBILITY
442_LIBCPP_CONSTEXPR
443launch
444operator~(launch __x)
445{
Howard Hinnant6a683bf2013-07-02 18:01:41 +0000446 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantf491e512013-06-29 18:38:17 +0000447}
448
449inline _LIBCPP_INLINE_VISIBILITY
450launch&
451operator&=(launch& __x, launch __y)
452{
453 __x = __x & __y; return __x;
454}
455
456inline _LIBCPP_INLINE_VISIBILITY
457launch&
458operator|=(launch& __x, launch __y)
459{
460 __x = __x | __y; return __x;
461}
462
463inline _LIBCPP_INLINE_VISIBILITY
464launch&
465operator^=(launch& __x, launch __y)
466{
467 __x = __x ^ __y; return __x;
468}
469
470#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
471
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000472//enum class future_status
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000473_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000474{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000475 ready,
476 timeout,
477 deferred
478};
Howard Hinnantf6d875f2011-12-02 19:36:40 +0000479_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000480
Howard Hinnant83eade62013-03-06 23:30:19 +0000481_LIBCPP_FUNC_VIS
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000482const error_category& future_category() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000483
484inline _LIBCPP_INLINE_VISIBILITY
485error_code
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000486make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000487{
488 return error_code(static_cast<int>(__e), future_category());
489}
490
491inline _LIBCPP_INLINE_VISIBILITY
492error_condition
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000493make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnanta6521722010-08-25 17:32:05 +0000494{
495 return error_condition(static_cast<int>(__e), future_category());
496}
497
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000498class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnanta6521722010-08-25 17:32:05 +0000499 : public logic_error
500{
501 error_code __ec_;
502public:
503 future_error(error_code __ec);
504
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000505 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +0000506 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnantac6de542011-07-07 21:03:52 +0000507
508 virtual ~future_error() _NOEXCEPT;
Howard Hinnanta6521722010-08-25 17:32:05 +0000509};
510
Howard Hinnant47499b12010-08-27 20:10:19 +0000511class __assoc_sub_state
512 : public __shared_count
513{
514protected:
515 exception_ptr __exception_;
516 mutable mutex __mut_;
517 mutable condition_variable __cv_;
518 unsigned __state_;
519
Howard Hinnant1694d232011-05-28 14:41:13 +0000520 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +0000521 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000522public:
523 enum
524 {
525 __constructed = 1,
526 __future_attached = 2,
527 ready = 4,
528 deferred = 8
529 };
530
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000531 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000532 __assoc_sub_state() : __state_(0) {}
533
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000535 bool __has_value() const
536 {return (__state_ & __constructed) || (__exception_ != nullptr);}
537
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant1b031c92013-01-14 20:01:24 +0000539 void __set_future_attached()
540 {
541 lock_guard<mutex> __lk(__mut_);
542 __state_ |= __future_attached;
543 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000544 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000545 bool __has_future_attached() const {return __state_ & __future_attached;}
546
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +0000548 void __set_deferred() {__state_ |= deferred;}
549
Howard Hinnant47499b12010-08-27 20:10:19 +0000550 void __make_ready();
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000552 bool __is_ready() const {return __state_ & ready;}
553
554 void set_value();
555 void set_value_at_thread_exit();
556
557 void set_exception(exception_ptr __p);
558 void set_exception_at_thread_exit(exception_ptr __p);
559
560 void copy();
561
Howard Hinnant54da3382010-08-30 18:46:21 +0000562 void wait();
Howard Hinnant47499b12010-08-27 20:10:19 +0000563 template <class _Rep, class _Period>
564 future_status
565 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
566 template <class _Clock, class _Duration>
567 future_status
568 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnant54da3382010-08-30 18:46:21 +0000569
570 virtual void __execute();
Howard Hinnant47499b12010-08-27 20:10:19 +0000571};
572
Howard Hinnantf39daa82010-08-28 21:01:06 +0000573template <class _Clock, class _Duration>
574future_status
575__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
576{
577 unique_lock<mutex> __lk(__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000578 if (__state_ & deferred)
579 return future_status::deferred;
580 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000581 __cv_.wait_until(__lk, __abs_time);
582 if (__state_ & ready)
583 return future_status::ready;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000584 return future_status::timeout;
585}
586
587template <class _Rep, class _Period>
588inline _LIBCPP_INLINE_VISIBILITY
589future_status
590__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
591{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000592 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000593}
594
Howard Hinnant99968442011-11-29 18:15:50 +0000595template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000596class __assoc_state
597 : public __assoc_sub_state
598{
599 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000600 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant47499b12010-08-27 20:10:19 +0000601protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000602 _Up __value_;
Howard Hinnant47499b12010-08-27 20:10:19 +0000603
Howard Hinnant1694d232011-05-28 14:41:13 +0000604 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000605public:
606
607 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000608#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000609 void set_value(_Arg&& __arg);
610#else
611 void set_value(_Arg& __arg);
612#endif
613
614 template <class _Arg>
Howard Hinnant73d21a42010-09-04 23:28:19 +0000615#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +0000616 void set_value_at_thread_exit(_Arg&& __arg);
617#else
618 void set_value_at_thread_exit(_Arg& __arg);
619#endif
620
Howard Hinnant99968442011-11-29 18:15:50 +0000621 _Rp move();
622 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant47499b12010-08-27 20:10:19 +0000623};
624
Howard Hinnant99968442011-11-29 18:15:50 +0000625template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000626void
Howard Hinnant99968442011-11-29 18:15:50 +0000627__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000628{
629 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000630 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000631 delete this;
632}
633
Howard Hinnant99968442011-11-29 18:15:50 +0000634template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000635template <class _Arg>
636void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000637#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000638__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000639#else
Howard Hinnant99968442011-11-29 18:15:50 +0000640__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000641#endif
642{
643 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000644#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000645 if (this->__has_value())
646 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000647#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000648 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000649 this->__state_ |= base::__constructed | base::ready;
650 __lk.unlock();
651 __cv_.notify_all();
652}
653
Howard Hinnant99968442011-11-29 18:15:50 +0000654template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000655template <class _Arg>
656void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000657#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000658__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000659#else
Howard Hinnant99968442011-11-29 18:15:50 +0000660__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant47499b12010-08-27 20:10:19 +0000661#endif
662{
663 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000664#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +0000665 if (this->__has_value())
666 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000667#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000668 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant47499b12010-08-27 20:10:19 +0000669 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000670 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant47499b12010-08-27 20:10:19 +0000671 __lk.unlock();
672}
673
Howard Hinnant99968442011-11-29 18:15:50 +0000674template <class _Rp>
675_Rp
676__assoc_state<_Rp>::move()
Howard Hinnant47499b12010-08-27 20:10:19 +0000677{
678 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000679 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000680 if (this->__exception_ != nullptr)
681 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000682 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant47499b12010-08-27 20:10:19 +0000683}
684
Howard Hinnant99968442011-11-29 18:15:50 +0000685template <class _Rp>
686typename add_lvalue_reference<_Rp>::type
687__assoc_state<_Rp>::copy()
Howard Hinnant47499b12010-08-27 20:10:19 +0000688{
689 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000690 this->__sub_wait(__lk);
Howard Hinnant47499b12010-08-27 20:10:19 +0000691 if (this->__exception_ != nullptr)
692 rethrow_exception(this->__exception_);
Howard Hinnant99968442011-11-29 18:15:50 +0000693 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000694}
695
Howard Hinnant99968442011-11-29 18:15:50 +0000696template <class _Rp>
697class __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000698 : public __assoc_sub_state
699{
700 typedef __assoc_sub_state base;
Howard Hinnant99968442011-11-29 18:15:50 +0000701 typedef _Rp* _Up;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000702protected:
Howard Hinnant99968442011-11-29 18:15:50 +0000703 _Up __value_;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000704
Howard Hinnant1694d232011-05-28 14:41:13 +0000705 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000706public:
707
Howard Hinnant99968442011-11-29 18:15:50 +0000708 void set_value(_Rp& __arg);
709 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000710
Howard Hinnant99968442011-11-29 18:15:50 +0000711 _Rp& copy();
Howard Hinnantf39daa82010-08-28 21:01:06 +0000712};
713
Howard Hinnant99968442011-11-29 18:15:50 +0000714template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000715void
Howard Hinnant99968442011-11-29 18:15:50 +0000716__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000717{
718 delete this;
719}
720
Howard Hinnant99968442011-11-29 18:15:50 +0000721template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000722void
Howard Hinnant99968442011-11-29 18:15:50 +0000723__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000724{
725 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000726#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000727 if (this->__has_value())
728 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000729#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000730 __value_ = &__arg;
731 this->__state_ |= base::__constructed | base::ready;
732 __lk.unlock();
733 __cv_.notify_all();
734}
735
Howard Hinnant99968442011-11-29 18:15:50 +0000736template <class _Rp>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000737void
Howard Hinnant99968442011-11-29 18:15:50 +0000738__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf39daa82010-08-28 21:01:06 +0000739{
740 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000741#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf39daa82010-08-28 21:01:06 +0000742 if (this->__has_value())
743 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant22ba71b2011-07-13 16:00:50 +0000744#endif
Howard Hinnantf39daa82010-08-28 21:01:06 +0000745 __value_ = &__arg;
746 this->__state_ |= base::__constructed;
Howard Hinnant5306d682010-10-14 19:18:04 +0000747 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000748 __lk.unlock();
749}
750
Howard Hinnant99968442011-11-29 18:15:50 +0000751template <class _Rp>
752_Rp&
753__assoc_state<_Rp&>::copy()
Howard Hinnantf39daa82010-08-28 21:01:06 +0000754{
755 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant54da3382010-08-30 18:46:21 +0000756 this->__sub_wait(__lk);
Howard Hinnantf39daa82010-08-28 21:01:06 +0000757 if (this->__exception_ != nullptr)
758 rethrow_exception(this->__exception_);
759 return *__value_;
760}
761
Howard Hinnant99968442011-11-29 18:15:50 +0000762template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000763class __assoc_state_alloc
Howard Hinnant99968442011-11-29 18:15:50 +0000764 : public __assoc_state<_Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +0000765{
Howard Hinnant99968442011-11-29 18:15:50 +0000766 typedef __assoc_state<_Rp> base;
Howard Hinnant47499b12010-08-27 20:10:19 +0000767 _Alloc __alloc_;
768
Howard Hinnant1694d232011-05-28 14:41:13 +0000769 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000770public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000771 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000772 explicit __assoc_state_alloc(const _Alloc& __a)
773 : __alloc_(__a) {}
774};
775
Howard Hinnant99968442011-11-29 18:15:50 +0000776template <class _Rp, class _Alloc>
Howard Hinnant47499b12010-08-27 20:10:19 +0000777void
Howard Hinnant99968442011-11-29 18:15:50 +0000778__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000779{
780 if (this->__state_ & base::__constructed)
Howard Hinnant99968442011-11-29 18:15:50 +0000781 reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
Howard Hinnant47499b12010-08-27 20:10:19 +0000782 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
783 this->~__assoc_state_alloc();
784 __a.deallocate(this, 1);
785}
786
Howard Hinnant99968442011-11-29 18:15:50 +0000787template <class _Rp, class _Alloc>
788class __assoc_state_alloc<_Rp&, _Alloc>
789 : public __assoc_state<_Rp&>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000790{
Howard Hinnant99968442011-11-29 18:15:50 +0000791 typedef __assoc_state<_Rp&> base;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000792 _Alloc __alloc_;
793
Howard Hinnant1694d232011-05-28 14:41:13 +0000794 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf39daa82010-08-28 21:01:06 +0000795public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000796 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf39daa82010-08-28 21:01:06 +0000797 explicit __assoc_state_alloc(const _Alloc& __a)
798 : __alloc_(__a) {}
799};
800
Howard Hinnant99968442011-11-29 18:15:50 +0000801template <class _Rp, class _Alloc>
Howard Hinnantf39daa82010-08-28 21:01:06 +0000802void
Howard Hinnant99968442011-11-29 18:15:50 +0000803__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf39daa82010-08-28 21:01:06 +0000804{
805 typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
806 this->~__assoc_state_alloc();
807 __a.deallocate(this, 1);
808}
809
Howard Hinnant47499b12010-08-27 20:10:19 +0000810template <class _Alloc>
811class __assoc_sub_state_alloc
812 : public __assoc_sub_state
813{
814 typedef __assoc_sub_state base;
815 _Alloc __alloc_;
816
Howard Hinnant1694d232011-05-28 14:41:13 +0000817 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant47499b12010-08-27 20:10:19 +0000818public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +0000819 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +0000820 explicit __assoc_sub_state_alloc(const _Alloc& __a)
821 : __alloc_(__a) {}
822};
823
824template <class _Alloc>
825void
Howard Hinnant1694d232011-05-28 14:41:13 +0000826__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +0000827{
Howard Hinnantf39daa82010-08-28 21:01:06 +0000828 typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
Howard Hinnant47499b12010-08-27 20:10:19 +0000829 this->~__assoc_sub_state_alloc();
830 __a.deallocate(this, 1);
831}
832
Howard Hinnant99968442011-11-29 18:15:50 +0000833template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000834class __deferred_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000835 : public __assoc_state<_Rp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000836{
Howard Hinnant99968442011-11-29 18:15:50 +0000837 typedef __assoc_state<_Rp> base;
Howard Hinnant54da3382010-08-30 18:46:21 +0000838
Howard Hinnant99968442011-11-29 18:15:50 +0000839 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000840
841public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000842#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000843 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000844#endif
845
846 virtual void __execute();
847};
848
Howard Hinnant73d21a42010-09-04 23:28:19 +0000849#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000850
Howard Hinnant99968442011-11-29 18:15:50 +0000851template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000852inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000853__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
854 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000855{
856 this->__set_deferred();
857}
858
Howard Hinnant73d21a42010-09-04 23:28:19 +0000859#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000860
Howard Hinnant99968442011-11-29 18:15:50 +0000861template <class _Rp, class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000862void
Howard Hinnant99968442011-11-29 18:15:50 +0000863__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000864{
865#ifndef _LIBCPP_NO_EXCEPTIONS
866 try
867 {
868#endif // _LIBCPP_NO_EXCEPTIONS
869 this->set_value(__func_());
870#ifndef _LIBCPP_NO_EXCEPTIONS
871 }
872 catch (...)
873 {
874 this->set_exception(current_exception());
875 }
876#endif // _LIBCPP_NO_EXCEPTIONS
877}
878
Howard Hinnant99968442011-11-29 18:15:50 +0000879template <class _Fp>
880class __deferred_assoc_state<void, _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000881 : public __assoc_sub_state
882{
883 typedef __assoc_sub_state base;
884
Howard Hinnant99968442011-11-29 18:15:50 +0000885 _Fp __func_;
Howard Hinnant54da3382010-08-30 18:46:21 +0000886
887public:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000888#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000889 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +0000890#endif
891
892 virtual void __execute();
893};
894
Howard Hinnant73d21a42010-09-04 23:28:19 +0000895#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000896
Howard Hinnant99968442011-11-29 18:15:50 +0000897template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000898inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000899__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
900 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant54da3382010-08-30 18:46:21 +0000901{
902 this->__set_deferred();
903}
904
Howard Hinnant73d21a42010-09-04 23:28:19 +0000905#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant54da3382010-08-30 18:46:21 +0000906
Howard Hinnant99968442011-11-29 18:15:50 +0000907template <class _Fp>
Howard Hinnant54da3382010-08-30 18:46:21 +0000908void
Howard Hinnant99968442011-11-29 18:15:50 +0000909__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnant54da3382010-08-30 18:46:21 +0000910{
911#ifndef _LIBCPP_NO_EXCEPTIONS
912 try
913 {
914#endif // _LIBCPP_NO_EXCEPTIONS
915 __func_();
916 this->set_value();
917#ifndef _LIBCPP_NO_EXCEPTIONS
918 }
919 catch (...)
920 {
921 this->set_exception(current_exception());
922 }
923#endif // _LIBCPP_NO_EXCEPTIONS
924}
925
Howard Hinnant99968442011-11-29 18:15:50 +0000926template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000927class __async_assoc_state
Howard Hinnant99968442011-11-29 18:15:50 +0000928 : public __assoc_state<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000929{
Howard Hinnant99968442011-11-29 18:15:50 +0000930 typedef __assoc_state<_Rp> base;
Howard Hinnant57cff292011-05-19 15:05:04 +0000931
Howard Hinnant99968442011-11-29 18:15:50 +0000932 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000933
Howard Hinnant1694d232011-05-28 14:41:13 +0000934 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000935public:
936#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000937 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000938#endif
939
940 virtual void __execute();
941};
942
943#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
944
Howard Hinnant99968442011-11-29 18:15:50 +0000945template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000946inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000947__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
948 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +0000949{
950}
951
952#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
953
Howard Hinnant99968442011-11-29 18:15:50 +0000954template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000955void
Howard Hinnant99968442011-11-29 18:15:50 +0000956__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +0000957{
958#ifndef _LIBCPP_NO_EXCEPTIONS
959 try
960 {
961#endif // _LIBCPP_NO_EXCEPTIONS
962 this->set_value(__func_());
963#ifndef _LIBCPP_NO_EXCEPTIONS
964 }
965 catch (...)
966 {
967 this->set_exception(current_exception());
968 }
969#endif // _LIBCPP_NO_EXCEPTIONS
970}
971
Howard Hinnant99968442011-11-29 18:15:50 +0000972template <class _Rp, class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000973void
Howard Hinnant99968442011-11-29 18:15:50 +0000974__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +0000975{
976 this->wait();
977 base::__on_zero_shared();
978}
979
Howard Hinnant99968442011-11-29 18:15:50 +0000980template <class _Fp>
981class __async_assoc_state<void, _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +0000982 : public __assoc_sub_state
983{
984 typedef __assoc_sub_state base;
985
Howard Hinnant99968442011-11-29 18:15:50 +0000986 _Fp __func_;
Howard Hinnant57cff292011-05-19 15:05:04 +0000987
Howard Hinnant1694d232011-05-28 14:41:13 +0000988 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant57cff292011-05-19 15:05:04 +0000989public:
990#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +0000991 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +0000992#endif
993
994 virtual void __execute();
995};
996
997#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
998
Howard Hinnant99968442011-11-29 18:15:50 +0000999template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001000inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001001__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1002 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant57cff292011-05-19 15:05:04 +00001003{
1004}
1005
1006#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1007
Howard Hinnant99968442011-11-29 18:15:50 +00001008template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001009void
Howard Hinnant99968442011-11-29 18:15:50 +00001010__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant57cff292011-05-19 15:05:04 +00001011{
1012#ifndef _LIBCPP_NO_EXCEPTIONS
1013 try
1014 {
1015#endif // _LIBCPP_NO_EXCEPTIONS
1016 __func_();
1017 this->set_value();
1018#ifndef _LIBCPP_NO_EXCEPTIONS
1019 }
1020 catch (...)
1021 {
1022 this->set_exception(current_exception());
1023 }
1024#endif // _LIBCPP_NO_EXCEPTIONS
1025}
1026
Howard Hinnant99968442011-11-29 18:15:50 +00001027template <class _Fp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001028void
Howard Hinnant99968442011-11-29 18:15:50 +00001029__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant57cff292011-05-19 15:05:04 +00001030{
1031 this->wait();
1032 base::__on_zero_shared();
1033}
1034
Howard Hinnant83eade62013-03-06 23:30:19 +00001035template <class _Rp> class _LIBCPP_TYPE_VIS promise;
1036template <class _Rp> class _LIBCPP_TYPE_VIS shared_future;
Howard Hinnant47499b12010-08-27 20:10:19 +00001037
1038// future
1039
Howard Hinnant83eade62013-03-06 23:30:19 +00001040template <class _Rp> class _LIBCPP_TYPE_VIS future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001041
Howard Hinnant99968442011-11-29 18:15:50 +00001042template <class _Rp, class _Fp>
1043future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00001044#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001045__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001046#else
Howard Hinnant99968442011-11-29 18:15:50 +00001047__make_deferred_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001048#endif
1049
Howard Hinnant99968442011-11-29 18:15:50 +00001050template <class _Rp, class _Fp>
1051future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00001052#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001053__make_async_assoc_state(_Fp&& __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001054#else
Howard Hinnant99968442011-11-29 18:15:50 +00001055__make_async_assoc_state(_Fp __f);
Howard Hinnant57cff292011-05-19 15:05:04 +00001056#endif
1057
Howard Hinnant99968442011-11-29 18:15:50 +00001058template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00001059class _LIBCPP_TYPE_VIS future
Howard Hinnant47499b12010-08-27 20:10:19 +00001060{
Howard Hinnant99968442011-11-29 18:15:50 +00001061 __assoc_state<_Rp>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001062
Howard Hinnant99968442011-11-29 18:15:50 +00001063 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001064
1065 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001066 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001067
Howard Hinnant73d21a42010-09-04 23:28:19 +00001068#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001069 template <class _R1, class _Fp>
1070 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1071 template <class _R1, class _Fp>
1072 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001073#else
Howard Hinnant99968442011-11-29 18:15:50 +00001074 template <class _R1, class _Fp>
1075 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1076 template <class _R1, class _Fp>
1077 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001078#endif
1079
Howard Hinnant47499b12010-08-27 20:10:19 +00001080public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001081 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001082 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001083#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001084 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001085 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001086 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1087 future(const future&) = delete;
1088 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001089 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001090 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001091 {
1092 future(std::move(__rhs)).swap(*this);
1093 return *this;
1094 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001095#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001096private:
1097 future(const future&);
1098 future& operator=(const future&);
1099public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001100#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001101 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001102 shared_future<_Rp> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001103
1104 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001105 _Rp get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001106
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001107 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001108 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001109
1110 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001111 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001112 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001113
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001114 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001115 void wait() const {__state_->wait();}
1116 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001117 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001118 future_status
1119 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1120 {return __state_->wait_for(__rel_time);}
1121 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001122 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001123 future_status
1124 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1125 {return __state_->wait_until(__abs_time);}
1126};
1127
Howard Hinnant99968442011-11-29 18:15:50 +00001128template <class _Rp>
1129future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001130 : __state_(__state)
1131{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001132#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001133 if (__state_->__has_future_attached())
1134 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001135#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001136 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001137 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001138}
1139
Howard Hinnant54da3382010-08-30 18:46:21 +00001140struct __release_shared_count
1141{
1142 void operator()(__shared_count* p) {p->__release_shared();}
1143};
1144
Howard Hinnant99968442011-11-29 18:15:50 +00001145template <class _Rp>
1146future<_Rp>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001147{
1148 if (__state_)
1149 __state_->__release_shared();
1150}
1151
Howard Hinnant99968442011-11-29 18:15:50 +00001152template <class _Rp>
1153_Rp
1154future<_Rp>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001155{
Howard Hinnant54da3382010-08-30 18:46:21 +00001156 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001157 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001158 __state_ = nullptr;
1159 return __s->move();
1160}
1161
Howard Hinnant99968442011-11-29 18:15:50 +00001162template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00001163class _LIBCPP_TYPE_VIS future<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001164{
Howard Hinnant99968442011-11-29 18:15:50 +00001165 __assoc_state<_Rp&>* __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001166
Howard Hinnant99968442011-11-29 18:15:50 +00001167 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant47499b12010-08-27 20:10:19 +00001168
1169 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001170 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001171
Howard Hinnant73d21a42010-09-04 23:28:19 +00001172#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001173 template <class _R1, class _Fp>
1174 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1175 template <class _R1, class _Fp>
1176 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001177#else
Howard Hinnant99968442011-11-29 18:15:50 +00001178 template <class _R1, class _Fp>
1179 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1180 template <class _R1, class _Fp>
1181 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001182#endif
1183
Howard Hinnant47499b12010-08-27 20:10:19 +00001184public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001185 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001186 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001187#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001188 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001189 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001190 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1191 future(const future&) = delete;
1192 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001193 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001194 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001195 {
1196 future(std::move(__rhs)).swap(*this);
1197 return *this;
1198 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001199#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001200private:
1201 future(const future&);
1202 future& operator=(const future&);
1203public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001204#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001205 ~future();
Howard Hinnant99968442011-11-29 18:15:50 +00001206 shared_future<_Rp&> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001207
1208 // retrieving the value
Howard Hinnant99968442011-11-29 18:15:50 +00001209 _Rp& get();
Howard Hinnant47499b12010-08-27 20:10:19 +00001210
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001212 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001213
1214 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001215 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001216 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001217
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001218 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001219 void wait() const {__state_->wait();}
1220 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001222 future_status
1223 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1224 {return __state_->wait_for(__rel_time);}
1225 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001226 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001227 future_status
1228 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1229 {return __state_->wait_until(__abs_time);}
1230};
1231
Howard Hinnant99968442011-11-29 18:15:50 +00001232template <class _Rp>
1233future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant47499b12010-08-27 20:10:19 +00001234 : __state_(__state)
1235{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001236#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001237 if (__state_->__has_future_attached())
1238 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001239#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001240 __state_->__add_shared();
Howard Hinnant54da3382010-08-30 18:46:21 +00001241 __state_->__set_future_attached();
Howard Hinnant47499b12010-08-27 20:10:19 +00001242}
1243
Howard Hinnant99968442011-11-29 18:15:50 +00001244template <class _Rp>
1245future<_Rp&>::~future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001246{
1247 if (__state_)
1248 __state_->__release_shared();
1249}
1250
Howard Hinnant99968442011-11-29 18:15:50 +00001251template <class _Rp>
1252_Rp&
1253future<_Rp&>::get()
Howard Hinnant47499b12010-08-27 20:10:19 +00001254{
Howard Hinnant54da3382010-08-30 18:46:21 +00001255 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnant99968442011-11-29 18:15:50 +00001256 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant47499b12010-08-27 20:10:19 +00001257 __state_ = nullptr;
1258 return __s->copy();
1259}
1260
1261template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001262class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001263{
1264 __assoc_sub_state* __state_;
1265
1266 explicit future(__assoc_sub_state* __state);
1267
1268 template <class> friend class promise;
Howard Hinnant99be8232010-09-03 18:39:25 +00001269 template <class> friend class shared_future;
Howard Hinnant54da3382010-08-30 18:46:21 +00001270
Howard Hinnant73d21a42010-09-04 23:28:19 +00001271#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001272 template <class _R1, class _Fp>
1273 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1274 template <class _R1, class _Fp>
1275 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001276#else
Howard Hinnant99968442011-11-29 18:15:50 +00001277 template <class _R1, class _Fp>
1278 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1279 template <class _R1, class _Fp>
1280 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001281#endif
1282
Howard Hinnant47499b12010-08-27 20:10:19 +00001283public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001284 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001285 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +00001286#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001287 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001288 future(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001289 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1290 future(const future&) = delete;
1291 future& operator=(const future&) = delete;
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001293 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001294 {
1295 future(std::move(__rhs)).swap(*this);
1296 return *this;
1297 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00001298#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001299private:
1300 future(const future&);
1301 future& operator=(const future&);
1302public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001303#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001304 ~future();
Howard Hinnant7de47902010-11-30 20:23:32 +00001305 shared_future<void> share();
Howard Hinnant47499b12010-08-27 20:10:19 +00001306
1307 // retrieving the value
1308 void get();
1309
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001310 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001311 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001312
1313 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001315 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant47499b12010-08-27 20:10:19 +00001316
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001317 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001318 void wait() const {__state_->wait();}
1319 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001320 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001321 future_status
1322 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1323 {return __state_->wait_for(__rel_time);}
1324 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant47499b12010-08-27 20:10:19 +00001326 future_status
1327 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1328 {return __state_->wait_until(__abs_time);}
1329};
1330
Howard Hinnant99968442011-11-29 18:15:50 +00001331template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00001332inline _LIBCPP_INLINE_VISIBILITY
1333void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001334swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00001335{
1336 __x.swap(__y);
1337}
1338
Howard Hinnant47499b12010-08-27 20:10:19 +00001339// promise<R>
1340
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001341template <class _Callable> class packaged_task;
Howard Hinnant54da3382010-08-30 18:46:21 +00001342
Howard Hinnant99968442011-11-29 18:15:50 +00001343template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00001344class _LIBCPP_TYPE_VIS promise
Howard Hinnant47499b12010-08-27 20:10:19 +00001345{
Howard Hinnant99968442011-11-29 18:15:50 +00001346 __assoc_state<_Rp>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001347
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001348 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001349 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001350
1351 template <class> friend class packaged_task;
Howard Hinnant47499b12010-08-27 20:10:19 +00001352public:
1353 promise();
1354 template <class _Alloc>
1355 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001356#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001357 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001358 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001359 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1360 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001361#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001362private:
1363 promise(const promise& __rhs);
1364public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001365#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001366 ~promise();
1367
1368 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001369#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001371 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001372 {
1373 promise(std::move(__rhs)).swap(*this);
1374 return *this;
1375 }
1376 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001377#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001378private:
1379 promise& operator=(const promise& __rhs);
1380public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001381#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001383 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001384
1385 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001386 future<_Rp> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001387
1388 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001389 void set_value(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001390#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001391 void set_value(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001392#endif
1393 void set_exception(exception_ptr __p);
1394
1395 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001396 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001397#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00001398 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001399#endif
1400 void set_exception_at_thread_exit(exception_ptr __p);
1401};
1402
Howard Hinnant99968442011-11-29 18:15:50 +00001403template <class _Rp>
1404promise<_Rp>::promise()
1405 : __state_(new __assoc_state<_Rp>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001406{
1407}
1408
Howard Hinnant99968442011-11-29 18:15:50 +00001409template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001410template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001411promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001412{
Howard Hinnant99968442011-11-29 18:15:50 +00001413 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001414 typedef __allocator_destructor<_A2> _D2;
1415 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001416 unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1417 ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001418 __state_ = __hold.release();
1419}
1420
Howard Hinnant99968442011-11-29 18:15:50 +00001421template <class _Rp>
1422promise<_Rp>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001423{
1424 if (__state_)
1425 {
1426 if (!__state_->__has_value() && __state_->use_count() > 1)
1427 __state_->set_exception(make_exception_ptr(
1428 future_error(make_error_code(future_errc::broken_promise))
1429 ));
1430 __state_->__release_shared();
1431 }
1432}
1433
Howard Hinnant99968442011-11-29 18:15:50 +00001434template <class _Rp>
1435future<_Rp>
1436promise<_Rp>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001437{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001438#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001439 if (__state_ == nullptr)
1440 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001441#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001442 return future<_Rp>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001443}
1444
Howard Hinnant99968442011-11-29 18:15:50 +00001445template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001446void
Howard Hinnant99968442011-11-29 18:15:50 +00001447promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001448{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001449#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001450 if (__state_ == nullptr)
1451 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001452#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001453 __state_->set_value(__r);
1454}
1455
Howard Hinnant73d21a42010-09-04 23:28:19 +00001456#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001457
Howard Hinnant99968442011-11-29 18:15:50 +00001458template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001459void
Howard Hinnant99968442011-11-29 18:15:50 +00001460promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001461{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001462#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001463 if (__state_ == nullptr)
1464 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001465#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001466 __state_->set_value(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001467}
1468
Howard Hinnant73d21a42010-09-04 23:28:19 +00001469#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001470
Howard Hinnant99968442011-11-29 18:15:50 +00001471template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001472void
Howard Hinnant99968442011-11-29 18:15:50 +00001473promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001474{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001475#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001476 if (__state_ == nullptr)
1477 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001478#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001479 __state_->set_exception(__p);
1480}
1481
Howard Hinnant99968442011-11-29 18:15:50 +00001482template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001483void
Howard Hinnant99968442011-11-29 18:15:50 +00001484promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001485{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001486#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001487 if (__state_ == nullptr)
1488 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001489#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001490 __state_->set_value_at_thread_exit(__r);
1491}
1492
Howard Hinnant73d21a42010-09-04 23:28:19 +00001493#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001494
Howard Hinnant99968442011-11-29 18:15:50 +00001495template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001496void
Howard Hinnant99968442011-11-29 18:15:50 +00001497promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001498{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001499#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001500 if (__state_ == nullptr)
1501 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001502#endif
Howard Hinnant0949eed2011-06-30 21:18:19 +00001503 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant47499b12010-08-27 20:10:19 +00001504}
1505
Howard Hinnant73d21a42010-09-04 23:28:19 +00001506#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001507
Howard Hinnant99968442011-11-29 18:15:50 +00001508template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001509void
Howard Hinnant99968442011-11-29 18:15:50 +00001510promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001511{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001512#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001513 if (__state_ == nullptr)
1514 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001515#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001516 __state_->set_exception_at_thread_exit(__p);
1517}
1518
1519// promise<R&>
1520
Howard Hinnant99968442011-11-29 18:15:50 +00001521template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00001522class _LIBCPP_TYPE_VIS promise<_Rp&>
Howard Hinnant47499b12010-08-27 20:10:19 +00001523{
Howard Hinnant99968442011-11-29 18:15:50 +00001524 __assoc_state<_Rp&>* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001525
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001527 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001528
1529 template <class> friend class packaged_task;
1530
Howard Hinnant47499b12010-08-27 20:10:19 +00001531public:
1532 promise();
1533 template <class _Allocator>
1534 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001535#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001537 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001538 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1539 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001540#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001541private:
1542 promise(const promise& __rhs);
1543public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001544#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001545 ~promise();
1546
1547 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001548#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001550 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001551 {
1552 promise(std::move(__rhs)).swap(*this);
1553 return *this;
1554 }
1555 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001556#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001557private:
1558 promise& operator=(const promise& __rhs);
1559public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001560#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001562 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001563
1564 // retrieving the result
Howard Hinnant99968442011-11-29 18:15:50 +00001565 future<_Rp&> get_future();
Howard Hinnant47499b12010-08-27 20:10:19 +00001566
1567 // setting the result
Howard Hinnant99968442011-11-29 18:15:50 +00001568 void set_value(_Rp& __r);
Howard Hinnant47499b12010-08-27 20:10:19 +00001569 void set_exception(exception_ptr __p);
1570
1571 // setting the result with deferred notification
Howard Hinnant99968442011-11-29 18:15:50 +00001572 void set_value_at_thread_exit(_Rp&);
Howard Hinnant47499b12010-08-27 20:10:19 +00001573 void set_exception_at_thread_exit(exception_ptr __p);
1574};
1575
Howard Hinnant99968442011-11-29 18:15:50 +00001576template <class _Rp>
1577promise<_Rp&>::promise()
1578 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant47499b12010-08-27 20:10:19 +00001579{
1580}
1581
Howard Hinnant99968442011-11-29 18:15:50 +00001582template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001583template <class _Alloc>
Howard Hinnant99968442011-11-29 18:15:50 +00001584promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant47499b12010-08-27 20:10:19 +00001585{
Howard Hinnant99968442011-11-29 18:15:50 +00001586 typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
Howard Hinnant47499b12010-08-27 20:10:19 +00001587 typedef __allocator_destructor<_A2> _D2;
1588 _A2 __a(__a0);
Howard Hinnant99968442011-11-29 18:15:50 +00001589 unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1590 ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
Howard Hinnant47499b12010-08-27 20:10:19 +00001591 __state_ = __hold.release();
1592}
1593
Howard Hinnant99968442011-11-29 18:15:50 +00001594template <class _Rp>
1595promise<_Rp&>::~promise()
Howard Hinnant47499b12010-08-27 20:10:19 +00001596{
1597 if (__state_)
1598 {
1599 if (!__state_->__has_value() && __state_->use_count() > 1)
1600 __state_->set_exception(make_exception_ptr(
1601 future_error(make_error_code(future_errc::broken_promise))
1602 ));
1603 __state_->__release_shared();
1604 }
1605}
1606
Howard Hinnant99968442011-11-29 18:15:50 +00001607template <class _Rp>
1608future<_Rp&>
1609promise<_Rp&>::get_future()
Howard Hinnant47499b12010-08-27 20:10:19 +00001610{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001611#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001612 if (__state_ == nullptr)
1613 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001614#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001615 return future<_Rp&>(__state_);
Howard Hinnant47499b12010-08-27 20:10:19 +00001616}
1617
Howard Hinnant99968442011-11-29 18:15:50 +00001618template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001619void
Howard Hinnant99968442011-11-29 18:15:50 +00001620promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001621{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001622#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001623 if (__state_ == nullptr)
1624 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001625#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001626 __state_->set_value(__r);
1627}
1628
Howard Hinnant99968442011-11-29 18:15:50 +00001629template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001630void
Howard Hinnant99968442011-11-29 18:15:50 +00001631promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001632{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001633#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001634 if (__state_ == nullptr)
1635 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001636#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001637 __state_->set_exception(__p);
1638}
1639
Howard Hinnant99968442011-11-29 18:15:50 +00001640template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001641void
Howard Hinnant99968442011-11-29 18:15:50 +00001642promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant47499b12010-08-27 20:10:19 +00001643{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001644#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001645 if (__state_ == nullptr)
1646 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001647#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001648 __state_->set_value_at_thread_exit(__r);
1649}
1650
Howard Hinnant99968442011-11-29 18:15:50 +00001651template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001652void
Howard Hinnant99968442011-11-29 18:15:50 +00001653promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant47499b12010-08-27 20:10:19 +00001654{
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001655#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant47499b12010-08-27 20:10:19 +00001656 if (__state_ == nullptr)
1657 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant22ba71b2011-07-13 16:00:50 +00001658#endif
Howard Hinnant47499b12010-08-27 20:10:19 +00001659 __state_->set_exception_at_thread_exit(__p);
1660}
1661
1662// promise<void>
1663
1664template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00001665class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant47499b12010-08-27 20:10:19 +00001666{
1667 __assoc_sub_state* __state_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001668
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001669 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001670 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant54da3382010-08-30 18:46:21 +00001671
1672 template <class> friend class packaged_task;
1673
Howard Hinnant47499b12010-08-27 20:10:19 +00001674public:
1675 promise();
1676 template <class _Allocator>
1677 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001678#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001680 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001681 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1682 promise(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001683#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001684private:
1685 promise(const promise& __rhs);
1686public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001687#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001688 ~promise();
1689
1690 // assignment
Howard Hinnant73d21a42010-09-04 23:28:19 +00001691#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001692 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001693 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001694 {
1695 promise(std::move(__rhs)).swap(*this);
1696 return *this;
1697 }
1698 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant73d21a42010-09-04 23:28:19 +00001699#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant47499b12010-08-27 20:10:19 +00001700private:
1701 promise& operator=(const promise& __rhs);
1702public:
Howard Hinnant73d21a42010-09-04 23:28:19 +00001703#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001705 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant47499b12010-08-27 20:10:19 +00001706
1707 // retrieving the result
1708 future<void> get_future();
1709
1710 // setting the result
1711 void set_value();
1712 void set_exception(exception_ptr __p);
1713
1714 // setting the result with deferred notification
1715 void set_value_at_thread_exit();
1716 void set_exception_at_thread_exit(exception_ptr __p);
1717};
1718
1719template <class _Alloc>
1720promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1721{
1722 typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
1723 typedef __allocator_destructor<_A2> _D2;
1724 _A2 __a(__a0);
1725 unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1726 ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
1727 __state_ = __hold.release();
1728}
1729
Howard Hinnant99968442011-11-29 18:15:50 +00001730template <class _Rp>
Howard Hinnant47499b12010-08-27 20:10:19 +00001731inline _LIBCPP_INLINE_VISIBILITY
1732void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001733swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant47499b12010-08-27 20:10:19 +00001734{
1735 __x.swap(__y);
1736}
1737
Howard Hinnant99968442011-11-29 18:15:50 +00001738template <class _Rp, class _Alloc>
Howard Hinnant83eade62013-03-06 23:30:19 +00001739 struct _LIBCPP_TYPE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001740 : public true_type {};
Howard Hinnant47499b12010-08-27 20:10:19 +00001741
Howard Hinnant54da3382010-08-30 18:46:21 +00001742#ifndef _LIBCPP_HAS_NO_VARIADICS
1743
1744// packaged_task
1745
1746template<class _Fp> class __packaged_task_base;
1747
Howard Hinnant99968442011-11-29 18:15:50 +00001748template<class _Rp, class ..._ArgTypes>
1749class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001750{
1751 __packaged_task_base(const __packaged_task_base&);
1752 __packaged_task_base& operator=(const __packaged_task_base&);
1753public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001755 __packaged_task_base() {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00001757 virtual ~__packaged_task_base() {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001758 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001759 virtual void destroy() = 0;
1760 virtual void destroy_deallocate() = 0;
Howard Hinnant99968442011-11-29 18:15:50 +00001761 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnant54da3382010-08-30 18:46:21 +00001762};
1763
1764template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1765
Howard Hinnant99968442011-11-29 18:15:50 +00001766template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1767class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1768 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001769{
Howard Hinnant99968442011-11-29 18:15:50 +00001770 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001771public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001773 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001775 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001777 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnant54da3382010-08-30 18:46:21 +00001778 : __f_(__f, __a) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001779 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001780 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001781 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001782 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001783 virtual void destroy();
1784 virtual void destroy_deallocate();
Howard Hinnant99968442011-11-29 18:15:50 +00001785 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnant54da3382010-08-30 18:46:21 +00001786};
1787
Howard Hinnant99968442011-11-29 18:15:50 +00001788template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001789void
Howard Hinnant99968442011-11-29 18:15:50 +00001790__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001791 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001792{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001793 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnant54da3382010-08-30 18:46:21 +00001794}
1795
Howard Hinnant99968442011-11-29 18:15:50 +00001796template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001797void
Howard Hinnant99968442011-11-29 18:15:50 +00001798__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnant54da3382010-08-30 18:46:21 +00001799{
Howard Hinnant99968442011-11-29 18:15:50 +00001800 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001801}
1802
Howard Hinnant99968442011-11-29 18:15:50 +00001803template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001804void
Howard Hinnant99968442011-11-29 18:15:50 +00001805__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnant54da3382010-08-30 18:46:21 +00001806{
Howard Hinnant99968442011-11-29 18:15:50 +00001807 typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
1808 _Ap __a(__f_.second());
1809 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnant54da3382010-08-30 18:46:21 +00001810 __a.deallocate(this, 1);
1811}
1812
Howard Hinnant99968442011-11-29 18:15:50 +00001813template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1814_Rp
1815__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnant54da3382010-08-30 18:46:21 +00001816{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001817 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00001818}
1819
Howard Hinnant2b1b2d42011-06-14 19:58:17 +00001820template <class _Callable> class __packaged_task_function;
Howard Hinnant54da3382010-08-30 18:46:21 +00001821
Howard Hinnant99968442011-11-29 18:15:50 +00001822template<class _Rp, class ..._ArgTypes>
1823class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00001824{
Howard Hinnant99968442011-11-29 18:15:50 +00001825 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant78f0de22013-01-21 17:26:55 +00001826 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnant54da3382010-08-30 18:46:21 +00001827 __base* __f_;
1828
1829public:
Howard Hinnant99968442011-11-29 18:15:50 +00001830 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00001831
1832 // construct/copy/destroy:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00001833 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001834 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00001835 template<class _Fp>
1836 __packaged_task_function(_Fp&& __f);
1837 template<class _Fp, class _Alloc>
1838 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnant54da3382010-08-30 18:46:21 +00001839
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001840 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1841 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001842
1843 __packaged_task_function(const __packaged_task_function&) = delete;
1844 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1845
1846 ~__packaged_task_function();
1847
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001848 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnant54da3382010-08-30 18:46:21 +00001849
Howard Hinnant99968442011-11-29 18:15:50 +00001850 _Rp operator()(_ArgTypes...) const;
Howard Hinnant54da3382010-08-30 18:46:21 +00001851};
1852
Howard Hinnant99968442011-11-29 18:15:50 +00001853template<class _Rp, class ..._ArgTypes>
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001854__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001855{
1856 if (__f.__f_ == nullptr)
1857 __f_ = nullptr;
1858 else if (__f.__f_ == (__base*)&__f.__buf_)
1859 {
1860 __f_ = (__base*)&__buf_;
1861 __f.__f_->__move_to(__f_);
1862 }
1863 else
1864 {
1865 __f_ = __f.__f_;
1866 __f.__f_ = nullptr;
1867 }
1868}
1869
Howard Hinnant99968442011-11-29 18:15:50 +00001870template<class _Rp, class ..._ArgTypes>
1871template <class _Fp>
1872__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001873 : __f_(nullptr)
1874{
Howard Hinnant99968442011-11-29 18:15:50 +00001875 typedef typename remove_reference<_Fp>::type _FR;
1876 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001877 if (sizeof(_FF) <= sizeof(__buf_))
1878 {
1879 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001880 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001881 }
1882 else
1883 {
Howard Hinnant99968442011-11-29 18:15:50 +00001884 typedef allocator<_FF> _Ap;
1885 _Ap __a;
1886 typedef __allocator_destructor<_Ap> _Dp;
1887 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1888 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001889 __f_ = __hold.release();
1890 }
1891}
1892
Howard Hinnant99968442011-11-29 18:15:50 +00001893template<class _Rp, class ..._ArgTypes>
1894template <class _Fp, class _Alloc>
1895__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1896 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00001897 : __f_(nullptr)
1898{
1899 typedef allocator_traits<_Alloc> __alloc_traits;
Howard Hinnant99968442011-11-29 18:15:50 +00001900 typedef typename remove_reference<_Fp>::type _FR;
1901 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnant54da3382010-08-30 18:46:21 +00001902 if (sizeof(_FF) <= sizeof(__buf_))
1903 {
1904 __f_ = (__base*)&__buf_;
Howard Hinnant99968442011-11-29 18:15:50 +00001905 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnant54da3382010-08-30 18:46:21 +00001906 }
1907 else
1908 {
1909 typedef typename __alloc_traits::template
1910#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
1911 rebind_alloc<_FF>
1912#else
1913 rebind_alloc<_FF>::other
1914#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001915 _Ap;
1916 _Ap __a(__a0);
1917 typedef __allocator_destructor<_Ap> _Dp;
1918 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1919 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
Howard Hinnant54da3382010-08-30 18:46:21 +00001920 __f_ = __hold.release();
1921 }
1922}
1923
Howard Hinnant99968442011-11-29 18:15:50 +00001924template<class _Rp, class ..._ArgTypes>
1925__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001926__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001927{
1928 if (__f_ == (__base*)&__buf_)
1929 __f_->destroy();
1930 else if (__f_)
1931 __f_->destroy_deallocate();
1932 __f_ = nullptr;
1933 if (__f.__f_ == nullptr)
1934 __f_ = nullptr;
1935 else if (__f.__f_ == (__base*)&__f.__buf_)
1936 {
1937 __f_ = (__base*)&__buf_;
1938 __f.__f_->__move_to(__f_);
1939 }
1940 else
1941 {
1942 __f_ = __f.__f_;
1943 __f.__f_ = nullptr;
1944 }
Argyrios Kyrtzidis1dc6f7a2012-10-13 02:03:45 +00001945 return *this;
Howard Hinnant54da3382010-08-30 18:46:21 +00001946}
1947
Howard Hinnant99968442011-11-29 18:15:50 +00001948template<class _Rp, class ..._ArgTypes>
1949__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnant54da3382010-08-30 18:46:21 +00001950{
1951 if (__f_ == (__base*)&__buf_)
1952 __f_->destroy();
1953 else if (__f_)
1954 __f_->destroy_deallocate();
1955}
1956
Howard Hinnant99968442011-11-29 18:15:50 +00001957template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001958void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00001959__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00001960{
1961 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1962 {
1963 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1964 __base* __t = (__base*)&__tempbuf;
1965 __f_->__move_to(__t);
1966 __f_->destroy();
1967 __f_ = nullptr;
1968 __f.__f_->__move_to((__base*)&__buf_);
1969 __f.__f_->destroy();
1970 __f.__f_ = nullptr;
1971 __f_ = (__base*)&__buf_;
1972 __t->__move_to((__base*)&__f.__buf_);
1973 __t->destroy();
1974 __f.__f_ = (__base*)&__f.__buf_;
1975 }
1976 else if (__f_ == (__base*)&__buf_)
1977 {
1978 __f_->__move_to((__base*)&__f.__buf_);
1979 __f_->destroy();
1980 __f_ = __f.__f_;
1981 __f.__f_ = (__base*)&__f.__buf_;
1982 }
1983 else if (__f.__f_ == (__base*)&__f.__buf_)
1984 {
1985 __f.__f_->__move_to((__base*)&__buf_);
1986 __f.__f_->destroy();
1987 __f.__f_ = __f_;
1988 __f_ = (__base*)&__buf_;
1989 }
1990 else
Howard Hinnant0949eed2011-06-30 21:18:19 +00001991 _VSTD::swap(__f_, __f.__f_);
Howard Hinnant54da3382010-08-30 18:46:21 +00001992}
1993
Howard Hinnant99968442011-11-29 18:15:50 +00001994template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00001995inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001996_Rp
1997__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnant54da3382010-08-30 18:46:21 +00001998{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001999 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002000}
2001
Howard Hinnant99968442011-11-29 18:15:50 +00002002template<class _Rp, class ..._ArgTypes>
Howard Hinnant83eade62013-03-06 23:30:19 +00002003class _LIBCPP_TYPE_VIS packaged_task<_Rp(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002004{
2005public:
Howard Hinnant99968442011-11-29 18:15:50 +00002006 typedef _Rp result_type;
Howard Hinnant54da3382010-08-30 18:46:21 +00002007
2008private:
2009 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2010 promise<result_type> __p_;
2011
2012public:
2013 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002015 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00002016 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002017 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002018 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2019 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002020 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002021 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2022 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002023 __p_(allocator_arg, __a) {}
2024 // ~packaged_task() = default;
2025
2026 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002027 packaged_task(const packaged_task&) = delete;
2028 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002029
2030 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002031 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002032 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002033 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002034 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002035 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002036 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002037 __f_ = _VSTD::move(__other.__f_);
2038 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002039 return *this;
2040 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002041 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002042 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002043 {
2044 __f_.swap(__other.__f_);
2045 __p_.swap(__other.__p_);
2046 }
2047
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002049 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002050
2051 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002052 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002053 future<result_type> get_future() {return __p_.get_future();}
2054
2055 // execution
2056 void operator()(_ArgTypes... __args);
2057 void make_ready_at_thread_exit(_ArgTypes... __args);
2058
2059 void reset();
2060};
2061
Howard Hinnant99968442011-11-29 18:15:50 +00002062template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002063void
Howard Hinnant99968442011-11-29 18:15:50 +00002064packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002065{
2066#ifndef _LIBCPP_NO_EXCEPTIONS
2067 if (__p_.__state_ == nullptr)
2068 throw future_error(make_error_code(future_errc::no_state));
2069 if (__p_.__state_->__has_value())
2070 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2071 try
2072 {
2073#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002074 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002075#ifndef _LIBCPP_NO_EXCEPTIONS
2076 }
2077 catch (...)
2078 {
2079 __p_.set_exception(current_exception());
2080 }
2081#endif // _LIBCPP_NO_EXCEPTIONS
2082}
2083
Howard Hinnant99968442011-11-29 18:15:50 +00002084template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002085void
Howard Hinnant99968442011-11-29 18:15:50 +00002086packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002087{
2088#ifndef _LIBCPP_NO_EXCEPTIONS
2089 if (__p_.__state_ == nullptr)
2090 throw future_error(make_error_code(future_errc::no_state));
2091 if (__p_.__state_->__has_value())
2092 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2093 try
2094 {
2095#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002096 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002097#ifndef _LIBCPP_NO_EXCEPTIONS
2098 }
2099 catch (...)
2100 {
2101 __p_.set_exception_at_thread_exit(current_exception());
2102 }
2103#endif // _LIBCPP_NO_EXCEPTIONS
2104}
2105
Howard Hinnant99968442011-11-29 18:15:50 +00002106template<class _Rp, class ..._ArgTypes>
Howard Hinnant54da3382010-08-30 18:46:21 +00002107void
Howard Hinnant99968442011-11-29 18:15:50 +00002108packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnant54da3382010-08-30 18:46:21 +00002109{
2110#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002111 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002112 throw future_error(make_error_code(future_errc::no_state));
2113#endif // _LIBCPP_NO_EXCEPTIONS
2114 __p_ = promise<result_type>();
2115}
2116
2117template<class ..._ArgTypes>
Howard Hinnant83eade62013-03-06 23:30:19 +00002118class _LIBCPP_TYPE_VIS packaged_task<void(_ArgTypes...)>
Howard Hinnant54da3382010-08-30 18:46:21 +00002119{
2120public:
2121 typedef void result_type;
2122
2123private:
2124 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2125 promise<result_type> __p_;
2126
2127public:
2128 // construction and destruction
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002129 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002130 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Howard Hinnant99968442011-11-29 18:15:50 +00002131 template <class _Fp>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002133 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
2134 template <class _Fp, class _Allocator>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002136 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2137 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnant54da3382010-08-30 18:46:21 +00002138 __p_(allocator_arg, __a) {}
2139 // ~packaged_task() = default;
2140
2141 // no copy
Howard Hinnant8131a012012-07-21 19:34:12 +00002142 packaged_task(const packaged_task&) = delete;
2143 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnant54da3382010-08-30 18:46:21 +00002144
2145 // move support
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002146 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002147 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +00002148 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002149 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002150 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002151 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002152 __f_ = _VSTD::move(__other.__f_);
2153 __p_ = _VSTD::move(__other.__p_);
Howard Hinnant54da3382010-08-30 18:46:21 +00002154 return *this;
2155 }
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002156 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002157 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002158 {
2159 __f_.swap(__other.__f_);
2160 __p_.swap(__other.__p_);
2161 }
2162
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002163 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002164 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnant54da3382010-08-30 18:46:21 +00002165
2166 // result retrieval
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002167 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant54da3382010-08-30 18:46:21 +00002168 future<result_type> get_future() {return __p_.get_future();}
2169
2170 // execution
2171 void operator()(_ArgTypes... __args);
2172 void make_ready_at_thread_exit(_ArgTypes... __args);
2173
2174 void reset();
2175};
2176
2177template<class ..._ArgTypes>
2178void
2179packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2180{
2181#ifndef _LIBCPP_NO_EXCEPTIONS
2182 if (__p_.__state_ == nullptr)
2183 throw future_error(make_error_code(future_errc::no_state));
2184 if (__p_.__state_->__has_value())
2185 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2186 try
2187 {
2188#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002189 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002190 __p_.set_value();
2191#ifndef _LIBCPP_NO_EXCEPTIONS
2192 }
2193 catch (...)
2194 {
2195 __p_.set_exception(current_exception());
2196 }
2197#endif // _LIBCPP_NO_EXCEPTIONS
2198}
2199
2200template<class ..._ArgTypes>
2201void
2202packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2203{
2204#ifndef _LIBCPP_NO_EXCEPTIONS
2205 if (__p_.__state_ == nullptr)
2206 throw future_error(make_error_code(future_errc::no_state));
2207 if (__p_.__state_->__has_value())
2208 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2209 try
2210 {
2211#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnant0949eed2011-06-30 21:18:19 +00002212 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002213 __p_.set_value_at_thread_exit();
2214#ifndef _LIBCPP_NO_EXCEPTIONS
2215 }
2216 catch (...)
2217 {
2218 __p_.set_exception_at_thread_exit(current_exception());
2219 }
2220#endif // _LIBCPP_NO_EXCEPTIONS
2221}
2222
2223template<class ..._ArgTypes>
2224void
2225packaged_task<void(_ArgTypes...)>::reset()
2226{
2227#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant7de47902010-11-30 20:23:32 +00002228 if (!valid())
Howard Hinnant54da3382010-08-30 18:46:21 +00002229 throw future_error(make_error_code(future_errc::no_state));
2230#endif // _LIBCPP_NO_EXCEPTIONS
2231 __p_ = promise<result_type>();
2232}
2233
2234template <class _Callable>
2235inline _LIBCPP_INLINE_VISIBILITY
2236void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002237swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnant54da3382010-08-30 18:46:21 +00002238{
2239 __x.swap(__y);
2240}
2241
2242template <class _Callable, class _Alloc>
Howard Hinnant83eade62013-03-06 23:30:19 +00002243struct _LIBCPP_TYPE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002244 : public true_type {};
Howard Hinnant54da3382010-08-30 18:46:21 +00002245
Howard Hinnant99968442011-11-29 18:15:50 +00002246template <class _Rp, class _Fp>
2247future<_Rp>
Howard Hinnant73d21a42010-09-04 23:28:19 +00002248#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002249__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002250#else
Howard Hinnant99968442011-11-29 18:15:50 +00002251__make_deferred_assoc_state(_Fp __f)
Howard Hinnant54da3382010-08-30 18:46:21 +00002252#endif
2253{
Howard Hinnant99968442011-11-29 18:15:50 +00002254 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2255 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2256 return future<_Rp>(__h.get());
Howard Hinnant54da3382010-08-30 18:46:21 +00002257}
2258
Howard Hinnant99968442011-11-29 18:15:50 +00002259template <class _Rp, class _Fp>
2260future<_Rp>
Howard Hinnant57cff292011-05-19 15:05:04 +00002261#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99968442011-11-29 18:15:50 +00002262__make_async_assoc_state(_Fp&& __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002263#else
Howard Hinnant99968442011-11-29 18:15:50 +00002264__make_async_assoc_state(_Fp __f)
Howard Hinnant57cff292011-05-19 15:05:04 +00002265#endif
2266{
Howard Hinnant99968442011-11-29 18:15:50 +00002267 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2268 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2269 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2270 return future<_Rp>(__h.get());
Howard Hinnant57cff292011-05-19 15:05:04 +00002271}
2272
Howard Hinnant99968442011-11-29 18:15:50 +00002273template <class _Fp, class... _Args>
Howard Hinnant57cff292011-05-19 15:05:04 +00002274class __async_func
2275{
Howard Hinnant99968442011-11-29 18:15:50 +00002276 tuple<_Fp, _Args...> __f_;
Howard Hinnant57cff292011-05-19 15:05:04 +00002277
2278public:
Howard Hinnant99968442011-11-29 18:15:50 +00002279 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant57cff292011-05-19 15:05:04 +00002280
2281 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002282 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnant0949eed2011-06-30 21:18:19 +00002283 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002284
2285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant0949eed2011-06-30 21:18:19 +00002286 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant57cff292011-05-19 15:05:04 +00002287
Howard Hinnant99968442011-11-29 18:15:50 +00002288 _Rp operator()()
Howard Hinnant57cff292011-05-19 15:05:04 +00002289 {
2290 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2291 return __execute(_Index());
2292 }
2293private:
2294 template <size_t ..._Indices>
Howard Hinnant99968442011-11-29 18:15:50 +00002295 _Rp
Howard Hinnant57cff292011-05-19 15:05:04 +00002296 __execute(__tuple_indices<_Indices...>)
2297 {
Howard Hinnant0949eed2011-06-30 21:18:19 +00002298 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant57cff292011-05-19 15:05:04 +00002299 }
2300};
2301
Howard Hinnant99968442011-11-29 18:15:50 +00002302template <class _Fp, class... _Args>
2303future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2304async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002305{
Howard Hinnant99968442011-11-29 18:15:50 +00002306 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2307 typedef typename _BF::_Rp _Rp;
2308 future<_Rp> __r;
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002309 if (int(__policy) & int(launch::async))
Howard Hinnant99968442011-11-29 18:15:50 +00002310 __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002311 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnantf6d875f2011-12-02 19:36:40 +00002312 else if (int(__policy) & int(launch::deferred))
Howard Hinnant99968442011-11-29 18:15:50 +00002313 __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002314 __decay_copy(_VSTD::forward<_Args>(__args))...));
Howard Hinnant54da3382010-08-30 18:46:21 +00002315 return __r;
2316}
2317
Howard Hinnant99968442011-11-29 18:15:50 +00002318template <class _Fp, class... _Args>
Howard Hinnant54da3382010-08-30 18:46:21 +00002319inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002320future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2321async(_Fp&& __f, _Args&&... __args)
Howard Hinnant54da3382010-08-30 18:46:21 +00002322{
Howard Hinnant99968442011-11-29 18:15:50 +00002323 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnant0949eed2011-06-30 21:18:19 +00002324 _VSTD::forward<_Args>(__args)...);
Howard Hinnant54da3382010-08-30 18:46:21 +00002325}
2326
2327#endif // _LIBCPP_HAS_NO_VARIADICS
2328
Howard Hinnante6e4d012010-09-03 21:46:37 +00002329// shared_future
2330
Howard Hinnant99968442011-11-29 18:15:50 +00002331template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00002332class _LIBCPP_TYPE_VIS shared_future
Howard Hinnant99be8232010-09-03 18:39:25 +00002333{
Howard Hinnant99968442011-11-29 18:15:50 +00002334 __assoc_state<_Rp>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002335
2336public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002337 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002338 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002340 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2341 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002342#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002343 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002344 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002345 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002346 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002347 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002348 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002349#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002350 ~shared_future();
2351 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002352#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002353 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002354 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002355 {
2356 shared_future(std::move(__rhs)).swap(*this);
2357 return *this;
2358 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002359#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002360
2361 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002362 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002363 const _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002364
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002366 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002367
2368 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002369 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002370 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002371
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002372 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002373 void wait() const {__state_->wait();}
2374 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002375 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002376 future_status
2377 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2378 {return __state_->wait_for(__rel_time);}
2379 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002380 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002381 future_status
2382 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2383 {return __state_->wait_until(__abs_time);}
2384};
2385
Howard Hinnant99968442011-11-29 18:15:50 +00002386template <class _Rp>
2387shared_future<_Rp>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002388{
2389 if (__state_)
2390 __state_->__release_shared();
2391}
2392
Howard Hinnant99968442011-11-29 18:15:50 +00002393template <class _Rp>
2394shared_future<_Rp>&
2395shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002396{
2397 if (__rhs.__state_)
2398 __rhs.__state_->__add_shared();
2399 if (__state_)
2400 __state_->__release_shared();
2401 __state_ = __rhs.__state_;
2402 return *this;
2403}
2404
Howard Hinnant99968442011-11-29 18:15:50 +00002405template <class _Rp>
Howard Hinnant83eade62013-03-06 23:30:19 +00002406class _LIBCPP_TYPE_VIS shared_future<_Rp&>
Howard Hinnant99be8232010-09-03 18:39:25 +00002407{
Howard Hinnant99968442011-11-29 18:15:50 +00002408 __assoc_state<_Rp&>* __state_;
Howard Hinnant99be8232010-09-03 18:39:25 +00002409
2410public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002412 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002413 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002414 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2415 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002416#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002418 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002419 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002421 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002422 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002423#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002424 ~shared_future();
2425 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002426#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002427 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002428 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002429 {
2430 shared_future(std::move(__rhs)).swap(*this);
2431 return *this;
2432 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002433#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002434
2435 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002436 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002437 _Rp& get() const {return __state_->copy();}
Howard Hinnant99be8232010-09-03 18:39:25 +00002438
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002440 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002441
2442 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002444 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002445
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002447 void wait() const {__state_->wait();}
2448 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002449 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002450 future_status
2451 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2452 {return __state_->wait_for(__rel_time);}
2453 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002454 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002455 future_status
2456 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2457 {return __state_->wait_until(__abs_time);}
2458};
2459
Howard Hinnant99968442011-11-29 18:15:50 +00002460template <class _Rp>
2461shared_future<_Rp&>::~shared_future()
Howard Hinnant99be8232010-09-03 18:39:25 +00002462{
2463 if (__state_)
2464 __state_->__release_shared();
2465}
2466
Howard Hinnant99968442011-11-29 18:15:50 +00002467template <class _Rp>
2468shared_future<_Rp&>&
2469shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant99be8232010-09-03 18:39:25 +00002470{
2471 if (__rhs.__state_)
2472 __rhs.__state_->__add_shared();
2473 if (__state_)
2474 __state_->__release_shared();
2475 __state_ = __rhs.__state_;
2476 return *this;
2477}
2478
2479template <>
Howard Hinnant83eade62013-03-06 23:30:19 +00002480class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant99be8232010-09-03 18:39:25 +00002481{
2482 __assoc_sub_state* __state_;
2483
2484public:
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002485 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002486 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002487 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002488 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2489 {if (__state_) __state_->__add_shared();}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002490#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002491 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002492 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002493 {__f.__state_ = nullptr;}
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002494 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002495 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant99be8232010-09-03 18:39:25 +00002496 {__rhs.__state_ = nullptr;}
Howard Hinnant73d21a42010-09-04 23:28:19 +00002497#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002498 ~shared_future();
2499 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant73d21a42010-09-04 23:28:19 +00002500#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002501 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002502 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002503 {
2504 shared_future(std::move(__rhs)).swap(*this);
2505 return *this;
2506 }
Howard Hinnant73d21a42010-09-04 23:28:19 +00002507#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant99be8232010-09-03 18:39:25 +00002508
2509 // retrieving the value
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002511 void get() const {__state_->copy();}
2512
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002513 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002514 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant99be8232010-09-03 18:39:25 +00002515
2516 // functions to check state
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002517 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002518 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant99be8232010-09-03 18:39:25 +00002519
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002520 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002521 void wait() const {__state_->wait();}
2522 template <class _Rep, class _Period>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002523 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002524 future_status
2525 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2526 {return __state_->wait_for(__rel_time);}
2527 template <class _Clock, class _Duration>
Howard Hinnant8c6cbb22010-09-22 14:16:26 +00002528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99be8232010-09-03 18:39:25 +00002529 future_status
2530 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2531 {return __state_->wait_until(__abs_time);}
2532};
2533
Howard Hinnant99968442011-11-29 18:15:50 +00002534template <class _Rp>
Howard Hinnant99be8232010-09-03 18:39:25 +00002535inline _LIBCPP_INLINE_VISIBILITY
2536void
Howard Hinnant8bf01dd2012-07-21 17:46:55 +00002537swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant99be8232010-09-03 18:39:25 +00002538{
2539 __x.swap(__y);
2540}
2541
Howard Hinnant99968442011-11-29 18:15:50 +00002542template <class _Rp>
Howard Hinnant7de47902010-11-30 20:23:32 +00002543inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002544shared_future<_Rp>
2545future<_Rp>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002546{
Howard Hinnant99968442011-11-29 18:15:50 +00002547 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002548}
2549
Howard Hinnant99968442011-11-29 18:15:50 +00002550template <class _Rp>
Howard Hinnante6e4d012010-09-03 21:46:37 +00002551inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00002552shared_future<_Rp&>
2553future<_Rp&>::share()
Howard Hinnante6e4d012010-09-03 21:46:37 +00002554{
Howard Hinnant99968442011-11-29 18:15:50 +00002555 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant7de47902010-11-30 20:23:32 +00002556}
2557
Howard Hinnanta4451512010-12-02 16:45:21 +00002558#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2559
Howard Hinnant7de47902010-11-30 20:23:32 +00002560inline _LIBCPP_INLINE_VISIBILITY
2561shared_future<void>
2562future<void>::share()
2563{
Howard Hinnant0949eed2011-06-30 21:18:19 +00002564 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6e4d012010-09-03 21:46:37 +00002565}
2566
Howard Hinnanta4451512010-12-02 16:45:21 +00002567#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2568
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00002569_LIBCPP_END_NAMESPACE_STD
2570
2571#endif // _LIBCPP_FUTURE