blob: ad7af72b12faabcfc1c5377a446740e9b5919dc4 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Howard Hinnantc566dc32010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-05-11 19:42:16 +00005//
Howard Hinnantee11c312010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc51e1022010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FUTURE
12#define _LIBCPP_FUTURE
13
14/*
15 future synopsis
16
17namespace std
18{
19
20enum class future_errc
21{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000022 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000023 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000024 no_state,
25 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000026};
27
28enum class launch
29{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000030 async = 1,
31 deferred = 2,
32 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000033};
34
35enum class future_status
36{
37 ready,
38 timeout,
39 deferred
40};
41
42template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000043error_code make_error_code(future_errc e) noexcept;
44error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000045
Howard Hinnant22448042012-07-21 17:46:55 +000046const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000047
48class future_error
49 : public logic_error
50{
51public:
52 future_error(error_code ec); // exposition only
53
Howard Hinnant22448042012-07-21 17:46:55 +000054 const error_code& code() const noexcept;
55 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000056};
57
58template <class R>
59class promise
60{
61public:
62 promise();
63 template <class Allocator>
64 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000065 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000066 promise(const promise& rhs) = delete;
67 ~promise();
68
69 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000070 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000071 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000072 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000073
74 // retrieving the result
75 future<R> get_future();
76
77 // setting the result
78 void set_value(const R& r);
79 void set_value(R&& r);
80 void set_exception(exception_ptr p);
81
82 // setting the result with deferred notification
83 void set_value_at_thread_exit(const R& r);
84 void set_value_at_thread_exit(R&& r);
85 void set_exception_at_thread_exit(exception_ptr p);
86};
87
88template <class R>
89class promise<R&>
90{
91public:
92 promise();
93 template <class Allocator>
94 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000095 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000096 promise(const promise& rhs) = delete;
97 ~promise();
98
99 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000100 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000101 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000102 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000103
104 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000105 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000106
107 // setting the result
108 void set_value(R& r);
109 void set_exception(exception_ptr p);
110
111 // setting the result with deferred notification
112 void set_value_at_thread_exit(R&);
113 void set_exception_at_thread_exit(exception_ptr p);
114};
115
116template <>
117class promise<void>
118{
119public:
120 promise();
121 template <class Allocator>
122 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000123 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000124 promise(const promise& rhs) = delete;
125 ~promise();
126
127 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000128 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000129 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000130 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000131
132 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000133 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000134
135 // setting the result
136 void set_value();
137 void set_exception(exception_ptr p);
138
139 // setting the result with deferred notification
140 void set_value_at_thread_exit();
141 void set_exception_at_thread_exit(exception_ptr p);
142};
143
Howard Hinnant22448042012-07-21 17:46:55 +0000144template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000145
146template <class R, class Alloc>
147 struct uses_allocator<promise<R>, Alloc> : public true_type {};
148
149template <class R>
150class future
151{
152public:
Howard Hinnant22448042012-07-21 17:46:55 +0000153 future() noexcept;
154 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000155 future(const future& rhs) = delete;
156 ~future();
157 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000158 future& operator=(future&&) noexcept;
159 shared_future<R> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000160
161 // retrieving the value
162 R get();
163
164 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000165 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000166
167 void wait() const;
168 template <class Rep, class Period>
169 future_status
170 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
171 template <class Clock, class Duration>
172 future_status
173 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
174};
175
176template <class R>
177class future<R&>
178{
179public:
Howard Hinnant22448042012-07-21 17:46:55 +0000180 future() noexcept;
181 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000182 future(const future& rhs) = delete;
183 ~future();
184 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000185 future& operator=(future&&) noexcept;
186 shared_future<R&> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187
188 // retrieving the value
189 R& get();
190
191 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000192 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000193
194 void wait() const;
195 template <class Rep, class Period>
196 future_status
197 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
198 template <class Clock, class Duration>
199 future_status
200 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
201};
202
203template <>
204class future<void>
205{
206public:
Howard Hinnant22448042012-07-21 17:46:55 +0000207 future() noexcept;
208 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000209 future(const future& rhs) = delete;
210 ~future();
211 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000212 future& operator=(future&&) noexcept;
213 shared_future<void> share();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000214
215 // retrieving the value
216 void get();
217
218 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000219 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000220
221 void wait() const;
222 template <class Rep, class Period>
223 future_status
224 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
225 template <class Clock, class Duration>
226 future_status
227 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
228};
229
230template <class R>
231class shared_future
232{
233public:
Howard Hinnant22448042012-07-21 17:46:55 +0000234 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000235 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000236 shared_future(future<R>&&) noexcept;
237 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000238 ~shared_future();
239 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000240 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000241
242 // retrieving the value
243 const R& get() const;
244
245 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000246 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000247
248 void wait() const;
249 template <class Rep, class Period>
250 future_status
251 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
252 template <class Clock, class Duration>
253 future_status
254 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
255};
256
257template <class R>
258class shared_future<R&>
259{
260public:
Howard Hinnant22448042012-07-21 17:46:55 +0000261 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000262 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000263 shared_future(future<R&>&&) noexcept;
264 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000265 ~shared_future();
266 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000267 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000268
269 // retrieving the value
270 R& get() const;
271
272 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000273 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000274
275 void wait() const;
276 template <class Rep, class Period>
277 future_status
278 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
279 template <class Clock, class Duration>
280 future_status
281 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
282};
283
284template <>
285class shared_future<void>
286{
287public:
Howard Hinnant22448042012-07-21 17:46:55 +0000288 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000289 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000290 shared_future(future<void>&&) noexcept;
291 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292 ~shared_future();
293 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000294 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000295
296 // retrieving the value
297 void get() const;
298
299 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000300 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000301
302 void wait() const;
303 template <class Rep, class Period>
304 future_status
305 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
306 template <class Clock, class Duration>
307 future_status
308 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
309};
310
Howard Hinnantc51e1022010-05-11 19:42:16 +0000311template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000312 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000313 async(F&& f, Args&&... args);
314
315template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000316 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000317 async(launch policy, F&& f, Args&&... args);
318
Howard Hinnantc566dc32010-05-11 21:36:01 +0000319template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000320
321template <class R, class... ArgTypes>
322class packaged_task<R(ArgTypes...)>
323{
324public:
325 typedef R result_type;
326
327 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000328 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000330 explicit packaged_task(F&& f);
331 template <class F, class Allocator>
332 explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
333 ~packaged_task();
334
335 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000336 packaged_task(const packaged_task&) = delete;
337 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000338
339 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000340 packaged_task(packaged_task&& other) noexcept;
341 packaged_task& operator=(packaged_task&& other) noexcept;
342 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000343
Howard Hinnant22448042012-07-21 17:46:55 +0000344 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000345
346 // result retrieval
347 future<R> get_future();
348
349 // execution
350 void operator()(ArgTypes... );
351 void make_ready_at_thread_exit(ArgTypes...);
352
353 void reset();
354};
355
356template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000357 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000358
359template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
360
361} // std
362
363*/
364
365#include <__config>
366#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000367#include <memory>
368#include <chrono>
369#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000370#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000371#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000373#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000374#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000375#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000377#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000378#error <future> is not supported on this single threaded system
379#else // !_LIBCPP_HAS_NO_THREADS
380
Howard Hinnantc51e1022010-05-11 19:42:16 +0000381_LIBCPP_BEGIN_NAMESPACE_STD
382
383//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000384_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000385{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000386 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000387 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000388 no_state,
389 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000391_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000392
Howard Hinnant684902d2010-09-22 14:16:26 +0000393template <>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000394struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000395
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000396#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
397template <>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000398struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000399#endif
400
Howard Hinnantc51e1022010-05-11 19:42:16 +0000401//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000402_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000403{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000404 async = 1,
405 deferred = 2,
406 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000408_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000409
Howard Hinnantda760a82013-06-29 18:38:17 +0000410#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
411
412#ifdef _LIBCXX_UNDERLYING_TYPE
413typedef underlying_type<launch>::type __launch_underlying_type;
414#else
415typedef int __launch_underlying_type;
416#endif
417
418inline _LIBCPP_INLINE_VISIBILITY
419_LIBCPP_CONSTEXPR
420launch
421operator&(launch __x, launch __y)
422{
423 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
424 static_cast<__launch_underlying_type>(__y));
425}
426
427inline _LIBCPP_INLINE_VISIBILITY
428_LIBCPP_CONSTEXPR
429launch
430operator|(launch __x, launch __y)
431{
432 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
433 static_cast<__launch_underlying_type>(__y));
434}
435
436inline _LIBCPP_INLINE_VISIBILITY
437_LIBCPP_CONSTEXPR
438launch
439operator^(launch __x, launch __y)
440{
441 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
442 static_cast<__launch_underlying_type>(__y));
443}
444
445inline _LIBCPP_INLINE_VISIBILITY
446_LIBCPP_CONSTEXPR
447launch
448operator~(launch __x)
449{
Howard Hinnant373d7602013-07-02 18:01:41 +0000450 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000451}
452
453inline _LIBCPP_INLINE_VISIBILITY
454launch&
455operator&=(launch& __x, launch __y)
456{
457 __x = __x & __y; return __x;
458}
459
460inline _LIBCPP_INLINE_VISIBILITY
461launch&
462operator|=(launch& __x, launch __y)
463{
464 __x = __x | __y; return __x;
465}
466
467inline _LIBCPP_INLINE_VISIBILITY
468launch&
469operator^=(launch& __x, launch __y)
470{
471 __x = __x ^ __y; return __x;
472}
473
474#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
475
Howard Hinnantc51e1022010-05-11 19:42:16 +0000476//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000477_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000478{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479 ready,
480 timeout,
481 deferred
482};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000483_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000484
Howard Hinnant8331b762013-03-06 23:30:19 +0000485_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000486const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000487
488inline _LIBCPP_INLINE_VISIBILITY
489error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000490make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000491{
492 return error_code(static_cast<int>(__e), future_category());
493}
494
495inline _LIBCPP_INLINE_VISIBILITY
496error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000497make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000498{
499 return error_condition(static_cast<int>(__e), future_category());
500}
501
Howard Hinnant684902d2010-09-22 14:16:26 +0000502class _LIBCPP_EXCEPTION_ABI future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000503 : public logic_error
504{
505 error_code __ec_;
506public:
507 future_error(error_code __ec);
508
Howard Hinnant684902d2010-09-22 14:16:26 +0000509 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000510 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000511
512 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000513};
514
Howard Hinnanta37d3cf2013-08-12 18:38:34 +0000515class _LIBCPP_TYPE_VIS __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000516 : public __shared_count
517{
518protected:
519 exception_ptr __exception_;
520 mutable mutex __mut_;
521 mutable condition_variable __cv_;
522 unsigned __state_;
523
Howard Hinnant719bda32011-05-28 14:41:13 +0000524 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000525 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000526public:
527 enum
528 {
529 __constructed = 1,
530 __future_attached = 2,
531 ready = 4,
532 deferred = 8
533 };
534
Howard Hinnant684902d2010-09-22 14:16:26 +0000535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000536 __assoc_sub_state() : __state_(0) {}
537
Howard Hinnant684902d2010-09-22 14:16:26 +0000538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000539 bool __has_value() const
540 {return (__state_ & __constructed) || (__exception_ != nullptr);}
541
Howard Hinnant684902d2010-09-22 14:16:26 +0000542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante667ecc2013-01-14 20:01:24 +0000543 void __set_future_attached()
544 {
545 lock_guard<mutex> __lk(__mut_);
546 __state_ |= __future_attached;
547 }
Howard Hinnant684902d2010-09-22 14:16:26 +0000548 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000549 bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000550
Howard Hinnant684902d2010-09-22 14:16:26 +0000551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000552 void __set_deferred() {__state_ |= deferred;}
553
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000554 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000555 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000556 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000557
558 void set_value();
559 void set_value_at_thread_exit();
560
561 void set_exception(exception_ptr __p);
562 void set_exception_at_thread_exit(exception_ptr __p);
563
564 void copy();
565
Howard Hinnantccdd2032010-08-30 18:46:21 +0000566 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000567 template <class _Rep, class _Period>
568 future_status
569 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
570 template <class _Clock, class _Duration>
571 future_status
572 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000573
574 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000575};
576
Howard Hinnantf4712b92010-08-28 21:01:06 +0000577template <class _Clock, class _Duration>
578future_status
579__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
580{
581 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000582 if (__state_ & deferred)
583 return future_status::deferred;
584 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000585 __cv_.wait_until(__lk, __abs_time);
586 if (__state_ & ready)
587 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000588 return future_status::timeout;
589}
590
591template <class _Rep, class _Period>
592inline _LIBCPP_INLINE_VISIBILITY
593future_status
594__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
595{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000596 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000597}
598
Howard Hinnantc834c512011-11-29 18:15:50 +0000599template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000600class __assoc_state
601 : public __assoc_sub_state
602{
603 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000604 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000605protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000606 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000607
Howard Hinnant719bda32011-05-28 14:41:13 +0000608 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000609public:
610
611 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000612#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000613 void set_value(_Arg&& __arg);
614#else
615 void set_value(_Arg& __arg);
616#endif
617
618 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000619#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000620 void set_value_at_thread_exit(_Arg&& __arg);
621#else
622 void set_value_at_thread_exit(_Arg& __arg);
623#endif
624
Howard Hinnantc834c512011-11-29 18:15:50 +0000625 _Rp move();
626 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000627};
628
Howard Hinnantc834c512011-11-29 18:15:50 +0000629template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000630void
Howard Hinnantc834c512011-11-29 18:15:50 +0000631__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000632{
633 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000634 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000635 delete this;
636}
637
Howard Hinnantc834c512011-11-29 18:15:50 +0000638template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000639template <class _Arg>
640void
Howard Hinnant74279a52010-09-04 23:28:19 +0000641#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000642__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000643#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000644__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000645#endif
646{
647 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000648#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000649 if (this->__has_value())
650 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000651#endif
Howard Hinnantc834c512011-11-29 18:15:50 +0000652 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000653 this->__state_ |= base::__constructed | base::ready;
654 __lk.unlock();
655 __cv_.notify_all();
656}
657
Howard Hinnantc834c512011-11-29 18:15:50 +0000658template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000659template <class _Arg>
660void
Howard Hinnant74279a52010-09-04 23:28:19 +0000661#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000662__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000663#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000664__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000665#endif
666{
667 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000668#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000669 if (this->__has_value())
670 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000671#endif
Howard Hinnantc834c512011-11-29 18:15:50 +0000672 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000673 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000674 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675 __lk.unlock();
676}
677
Howard Hinnantc834c512011-11-29 18:15:50 +0000678template <class _Rp>
679_Rp
680__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000681{
682 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000683 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000684 if (this->__exception_ != nullptr)
685 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000686 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000687}
688
Howard Hinnantc834c512011-11-29 18:15:50 +0000689template <class _Rp>
690typename add_lvalue_reference<_Rp>::type
691__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000692{
693 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000694 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000695 if (this->__exception_ != nullptr)
696 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000697 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000698}
699
Howard Hinnantc834c512011-11-29 18:15:50 +0000700template <class _Rp>
701class __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000702 : public __assoc_sub_state
703{
704 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000705 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000706protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000707 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000708
Howard Hinnant719bda32011-05-28 14:41:13 +0000709 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000710public:
711
Howard Hinnantc834c512011-11-29 18:15:50 +0000712 void set_value(_Rp& __arg);
713 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000714
Howard Hinnantc834c512011-11-29 18:15:50 +0000715 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000716};
717
Howard Hinnantc834c512011-11-29 18:15:50 +0000718template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000719void
Howard Hinnantc834c512011-11-29 18:15:50 +0000720__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000721{
722 delete this;
723}
724
Howard Hinnantc834c512011-11-29 18:15:50 +0000725template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000726void
Howard Hinnantc834c512011-11-29 18:15:50 +0000727__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728{
729 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000730#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf4712b92010-08-28 21:01:06 +0000731 if (this->__has_value())
732 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000733#endif
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000734 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000735 this->__state_ |= base::__constructed | base::ready;
736 __lk.unlock();
737 __cv_.notify_all();
738}
739
Howard Hinnantc834c512011-11-29 18:15:50 +0000740template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000741void
Howard Hinnantc834c512011-11-29 18:15:50 +0000742__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743{
744 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000745#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantf4712b92010-08-28 21:01:06 +0000746 if (this->__has_value())
747 throw future_error(make_error_code(future_errc::promise_already_satisfied));
Howard Hinnant83e6aad2011-07-13 16:00:50 +0000748#endif
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000749 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000750 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000751 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000752 __lk.unlock();
753}
754
Howard Hinnantc834c512011-11-29 18:15:50 +0000755template <class _Rp>
756_Rp&
757__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000758{
759 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000760 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000761 if (this->__exception_ != nullptr)
762 rethrow_exception(this->__exception_);
763 return *__value_;
764}
765
Howard Hinnantc834c512011-11-29 18:15:50 +0000766template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000767class __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000768 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000769{
Howard Hinnantc834c512011-11-29 18:15:50 +0000770 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000771 _Alloc __alloc_;
772
Howard Hinnant719bda32011-05-28 14:41:13 +0000773 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000774public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000776 explicit __assoc_state_alloc(const _Alloc& __a)
777 : __alloc_(__a) {}
778};
779
Howard Hinnantc834c512011-11-29 18:15:50 +0000780template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000781void
Howard Hinnantc834c512011-11-29 18:15:50 +0000782__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000783{
784 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000785 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000786 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
787 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000788 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000789 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000790 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000791 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000792}
793
Howard Hinnantc834c512011-11-29 18:15:50 +0000794template <class _Rp, class _Alloc>
795class __assoc_state_alloc<_Rp&, _Alloc>
796 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000797{
Howard Hinnantc834c512011-11-29 18:15:50 +0000798 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000799 _Alloc __alloc_;
800
Howard Hinnant719bda32011-05-28 14:41:13 +0000801 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000802public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000803 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000804 explicit __assoc_state_alloc(const _Alloc& __a)
805 : __alloc_(__a) {}
806};
807
Howard Hinnantc834c512011-11-29 18:15:50 +0000808template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000809void
Howard Hinnantc834c512011-11-29 18:15:50 +0000810__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000811{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000812 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
813 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000814 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000815 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000816 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000817 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000818}
819
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000820template <class _Alloc>
821class __assoc_sub_state_alloc
822 : public __assoc_sub_state
823{
824 typedef __assoc_sub_state base;
825 _Alloc __alloc_;
826
Howard Hinnant719bda32011-05-28 14:41:13 +0000827 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000828public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000829 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000830 explicit __assoc_sub_state_alloc(const _Alloc& __a)
831 : __alloc_(__a) {}
832};
833
834template <class _Alloc>
835void
Howard Hinnant719bda32011-05-28 14:41:13 +0000836__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000837{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000838 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
839 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000840 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000841 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000842 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000843 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000844}
845
Howard Hinnantc834c512011-11-29 18:15:50 +0000846template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000847class __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000848 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000849{
Howard Hinnantc834c512011-11-29 18:15:50 +0000850 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000851
Howard Hinnantc834c512011-11-29 18:15:50 +0000852 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000853
854public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000855#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000856 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000857#endif
858
859 virtual void __execute();
860};
861
Howard Hinnant74279a52010-09-04 23:28:19 +0000862#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000863
Howard Hinnantc834c512011-11-29 18:15:50 +0000864template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000865inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000866__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
867 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000868{
869 this->__set_deferred();
870}
871
Howard Hinnant74279a52010-09-04 23:28:19 +0000872#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000873
Howard Hinnantc834c512011-11-29 18:15:50 +0000874template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000875void
Howard Hinnantc834c512011-11-29 18:15:50 +0000876__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000877{
878#ifndef _LIBCPP_NO_EXCEPTIONS
879 try
880 {
881#endif // _LIBCPP_NO_EXCEPTIONS
882 this->set_value(__func_());
883#ifndef _LIBCPP_NO_EXCEPTIONS
884 }
885 catch (...)
886 {
887 this->set_exception(current_exception());
888 }
889#endif // _LIBCPP_NO_EXCEPTIONS
890}
891
Howard Hinnantc834c512011-11-29 18:15:50 +0000892template <class _Fp>
893class __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000894 : public __assoc_sub_state
895{
896 typedef __assoc_sub_state base;
897
Howard Hinnantc834c512011-11-29 18:15:50 +0000898 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000899
900public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000901#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000902 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000903#endif
904
905 virtual void __execute();
906};
907
Howard Hinnant74279a52010-09-04 23:28:19 +0000908#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000909
Howard Hinnantc834c512011-11-29 18:15:50 +0000910template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000911inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000912__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
913 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000914{
915 this->__set_deferred();
916}
917
Howard Hinnant74279a52010-09-04 23:28:19 +0000918#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000919
Howard Hinnantc834c512011-11-29 18:15:50 +0000920template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000921void
Howard Hinnantc834c512011-11-29 18:15:50 +0000922__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000923{
924#ifndef _LIBCPP_NO_EXCEPTIONS
925 try
926 {
927#endif // _LIBCPP_NO_EXCEPTIONS
928 __func_();
929 this->set_value();
930#ifndef _LIBCPP_NO_EXCEPTIONS
931 }
932 catch (...)
933 {
934 this->set_exception(current_exception());
935 }
936#endif // _LIBCPP_NO_EXCEPTIONS
937}
938
Howard Hinnantc834c512011-11-29 18:15:50 +0000939template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000940class __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000941 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000942{
Howard Hinnantc834c512011-11-29 18:15:50 +0000943 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000944
Howard Hinnantc834c512011-11-29 18:15:50 +0000945 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000946
Howard Hinnant719bda32011-05-28 14:41:13 +0000947 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000948public:
949#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000950 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000951#endif
952
953 virtual void __execute();
954};
955
956#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
957
Howard Hinnantc834c512011-11-29 18:15:50 +0000958template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000959inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000960__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
961 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000962{
963}
964
965#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
966
Howard Hinnantc834c512011-11-29 18:15:50 +0000967template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000968void
Howard Hinnantc834c512011-11-29 18:15:50 +0000969__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000970{
971#ifndef _LIBCPP_NO_EXCEPTIONS
972 try
973 {
974#endif // _LIBCPP_NO_EXCEPTIONS
975 this->set_value(__func_());
976#ifndef _LIBCPP_NO_EXCEPTIONS
977 }
978 catch (...)
979 {
980 this->set_exception(current_exception());
981 }
982#endif // _LIBCPP_NO_EXCEPTIONS
983}
984
Howard Hinnantc834c512011-11-29 18:15:50 +0000985template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000986void
Howard Hinnantc834c512011-11-29 18:15:50 +0000987__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000988{
989 this->wait();
990 base::__on_zero_shared();
991}
992
Howard Hinnantc834c512011-11-29 18:15:50 +0000993template <class _Fp>
994class __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000995 : public __assoc_sub_state
996{
997 typedef __assoc_sub_state base;
998
Howard Hinnantc834c512011-11-29 18:15:50 +0000999 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001000
Howard Hinnant719bda32011-05-28 14:41:13 +00001001 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001002public:
1003#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001004 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001005#endif
1006
1007 virtual void __execute();
1008};
1009
1010#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1011
Howard Hinnantc834c512011-11-29 18:15:50 +00001012template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001013inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001014__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1015 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001016{
1017}
1018
1019#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1020
Howard Hinnantc834c512011-11-29 18:15:50 +00001021template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001022void
Howard Hinnantc834c512011-11-29 18:15:50 +00001023__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001024{
1025#ifndef _LIBCPP_NO_EXCEPTIONS
1026 try
1027 {
1028#endif // _LIBCPP_NO_EXCEPTIONS
1029 __func_();
1030 this->set_value();
1031#ifndef _LIBCPP_NO_EXCEPTIONS
1032 }
1033 catch (...)
1034 {
1035 this->set_exception(current_exception());
1036 }
1037#endif // _LIBCPP_NO_EXCEPTIONS
1038}
1039
Howard Hinnantc834c512011-11-29 18:15:50 +00001040template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001041void
Howard Hinnantc834c512011-11-29 18:15:50 +00001042__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001043{
1044 this->wait();
1045 base::__on_zero_shared();
1046}
1047
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001048template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
1049template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001050
1051// future
1052
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001053template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001054
Howard Hinnantc834c512011-11-29 18:15:50 +00001055template <class _Rp, class _Fp>
1056future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001057#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001058__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001059#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001060__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001061#endif
1062
Howard Hinnantc834c512011-11-29 18:15:50 +00001063template <class _Rp, class _Fp>
1064future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001065#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001066__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001067#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001068__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001069#endif
1070
Howard Hinnantc834c512011-11-29 18:15:50 +00001071template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001072class _LIBCPP_TYPE_VIS_ONLY future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001073{
Howard Hinnantc834c512011-11-29 18:15:50 +00001074 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001075
Howard Hinnantc834c512011-11-29 18:15:50 +00001076 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001077
1078 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001079 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001080
Howard Hinnant74279a52010-09-04 23:28:19 +00001081#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001082 template <class _R1, class _Fp>
1083 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1084 template <class _R1, class _Fp>
1085 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001086#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001087 template <class _R1, class _Fp>
1088 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1089 template <class _R1, class _Fp>
1090 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001091#endif
1092
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001093public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001094 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001095 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001096#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001097 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001098 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001099 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1100 future(const future&) = delete;
1101 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001102 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001103 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001104 {
1105 future(std::move(__rhs)).swap(*this);
1106 return *this;
1107 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001108#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001109private:
1110 future(const future&);
1111 future& operator=(const future&);
1112public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001113#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001114 ~future();
Howard Hinnantc834c512011-11-29 18:15:50 +00001115 shared_future<_Rp> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001116
1117 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001118 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001119
Howard Hinnant684902d2010-09-22 14:16:26 +00001120 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001121 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001122
1123 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001124 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001125 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001126
Howard Hinnant684902d2010-09-22 14:16:26 +00001127 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001128 void wait() const {__state_->wait();}
1129 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001130 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001131 future_status
1132 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1133 {return __state_->wait_for(__rel_time);}
1134 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001136 future_status
1137 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1138 {return __state_->wait_until(__abs_time);}
1139};
1140
Howard Hinnantc834c512011-11-29 18:15:50 +00001141template <class _Rp>
1142future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001143 : __state_(__state)
1144{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001145#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001146 if (__state_->__has_future_attached())
1147 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001148#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001149 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001150 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001151}
1152
Howard Hinnantccdd2032010-08-30 18:46:21 +00001153struct __release_shared_count
1154{
1155 void operator()(__shared_count* p) {p->__release_shared();}
1156};
1157
Howard Hinnantc834c512011-11-29 18:15:50 +00001158template <class _Rp>
1159future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001160{
1161 if (__state_)
1162 __state_->__release_shared();
1163}
1164
Howard Hinnantc834c512011-11-29 18:15:50 +00001165template <class _Rp>
1166_Rp
1167future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001168{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001169 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001170 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001171 __state_ = nullptr;
1172 return __s->move();
1173}
1174
Howard Hinnantc834c512011-11-29 18:15:50 +00001175template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001176class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001177{
Howard Hinnantc834c512011-11-29 18:15:50 +00001178 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001179
Howard Hinnantc834c512011-11-29 18:15:50 +00001180 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001181
1182 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001183 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001184
Howard Hinnant74279a52010-09-04 23:28:19 +00001185#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001186 template <class _R1, class _Fp>
1187 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1188 template <class _R1, class _Fp>
1189 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001190#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001191 template <class _R1, class _Fp>
1192 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1193 template <class _R1, class _Fp>
1194 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001195#endif
1196
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001197public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001198 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001199 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001200#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001201 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001202 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001203 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1204 future(const future&) = delete;
1205 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001206 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001207 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001208 {
1209 future(std::move(__rhs)).swap(*this);
1210 return *this;
1211 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001212#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001213private:
1214 future(const future&);
1215 future& operator=(const future&);
1216public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001217#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001218 ~future();
Howard Hinnantc834c512011-11-29 18:15:50 +00001219 shared_future<_Rp&> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001220
1221 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001222 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001223
Howard Hinnant684902d2010-09-22 14:16:26 +00001224 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001225 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001226
1227 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001228 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001229 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001230
Howard Hinnant684902d2010-09-22 14:16:26 +00001231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001232 void wait() const {__state_->wait();}
1233 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001235 future_status
1236 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1237 {return __state_->wait_for(__rel_time);}
1238 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001240 future_status
1241 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1242 {return __state_->wait_until(__abs_time);}
1243};
1244
Howard Hinnantc834c512011-11-29 18:15:50 +00001245template <class _Rp>
1246future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001247 : __state_(__state)
1248{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001249#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001250 if (__state_->__has_future_attached())
1251 throw future_error(make_error_code(future_errc::future_already_retrieved));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001252#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001253 __state_->__add_shared();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001254 __state_->__set_future_attached();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001255}
1256
Howard Hinnantc834c512011-11-29 18:15:50 +00001257template <class _Rp>
1258future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001259{
1260 if (__state_)
1261 __state_->__release_shared();
1262}
1263
Howard Hinnantc834c512011-11-29 18:15:50 +00001264template <class _Rp>
1265_Rp&
1266future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001267{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001268 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001269 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001270 __state_ = nullptr;
1271 return __s->copy();
1272}
1273
1274template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001275class _LIBCPP_TYPE_VIS future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001276{
1277 __assoc_sub_state* __state_;
1278
1279 explicit future(__assoc_sub_state* __state);
1280
1281 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001282 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001283
Howard Hinnant74279a52010-09-04 23:28:19 +00001284#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001285 template <class _R1, class _Fp>
1286 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1287 template <class _R1, class _Fp>
1288 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001289#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001290 template <class _R1, class _Fp>
1291 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1292 template <class _R1, class _Fp>
1293 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001294#endif
1295
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001296public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001297 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001298 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001299#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001301 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001302 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1303 future(const future&) = delete;
1304 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001306 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001307 {
1308 future(std::move(__rhs)).swap(*this);
1309 return *this;
1310 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001311#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001312private:
1313 future(const future&);
1314 future& operator=(const future&);
1315public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001316#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001317 ~future();
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00001318 shared_future<void> share();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001319
1320 // retrieving the value
1321 void get();
1322
Howard Hinnant684902d2010-09-22 14:16:26 +00001323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001324 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001325
1326 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001328 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001329
Howard Hinnant684902d2010-09-22 14:16:26 +00001330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001331 void wait() const {__state_->wait();}
1332 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001334 future_status
1335 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1336 {return __state_->wait_for(__rel_time);}
1337 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001338 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001339 future_status
1340 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1341 {return __state_->wait_until(__abs_time);}
1342};
1343
Howard Hinnantc834c512011-11-29 18:15:50 +00001344template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001345inline _LIBCPP_INLINE_VISIBILITY
1346void
Howard Hinnant22448042012-07-21 17:46:55 +00001347swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001348{
1349 __x.swap(__y);
1350}
1351
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001352// promise<R>
1353
Howard Hinnant944510a2011-06-14 19:58:17 +00001354template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001355
Howard Hinnantc834c512011-11-29 18:15:50 +00001356template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001357class _LIBCPP_TYPE_VIS_ONLY promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001358{
Howard Hinnantc834c512011-11-29 18:15:50 +00001359 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001360
Howard Hinnant684902d2010-09-22 14:16:26 +00001361 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001362 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001363
1364 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001365public:
1366 promise();
1367 template <class _Alloc>
1368 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001369#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001371 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001372 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1373 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001374#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001375private:
1376 promise(const promise& __rhs);
1377public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001378#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001379 ~promise();
1380
1381 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001382#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001384 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001385 {
1386 promise(std::move(__rhs)).swap(*this);
1387 return *this;
1388 }
1389 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001390#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001391private:
1392 promise& operator=(const promise& __rhs);
1393public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001394#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001396 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001397
1398 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001399 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001400
1401 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001402 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001403#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001404 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001405#endif
1406 void set_exception(exception_ptr __p);
1407
1408 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001409 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001410#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001411 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001412#endif
1413 void set_exception_at_thread_exit(exception_ptr __p);
1414};
1415
Howard Hinnantc834c512011-11-29 18:15:50 +00001416template <class _Rp>
1417promise<_Rp>::promise()
1418 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001419{
1420}
1421
Howard Hinnantc834c512011-11-29 18:15:50 +00001422template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001423template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001424promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001425{
Eric Fiselier0d109272014-10-23 06:24:45 +00001426 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1427 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001428 typedef __allocator_destructor<_A2> _D2;
1429 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001430 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1431 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1432 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001433}
1434
Howard Hinnantc834c512011-11-29 18:15:50 +00001435template <class _Rp>
1436promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001437{
1438 if (__state_)
1439 {
1440 if (!__state_->__has_value() && __state_->use_count() > 1)
1441 __state_->set_exception(make_exception_ptr(
1442 future_error(make_error_code(future_errc::broken_promise))
1443 ));
1444 __state_->__release_shared();
1445 }
1446}
1447
Howard Hinnantc834c512011-11-29 18:15:50 +00001448template <class _Rp>
1449future<_Rp>
1450promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001451{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001452#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001453 if (__state_ == nullptr)
1454 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001455#endif
Howard Hinnantc834c512011-11-29 18:15:50 +00001456 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001457}
1458
Howard Hinnantc834c512011-11-29 18:15:50 +00001459template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001460void
Howard Hinnantc834c512011-11-29 18:15:50 +00001461promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001462{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001463#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001464 if (__state_ == nullptr)
1465 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001466#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001467 __state_->set_value(__r);
1468}
1469
Howard Hinnant74279a52010-09-04 23:28:19 +00001470#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001471
Howard Hinnantc834c512011-11-29 18:15:50 +00001472template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001473void
Howard Hinnantc834c512011-11-29 18:15:50 +00001474promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001475{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001476#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001477 if (__state_ == nullptr)
1478 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001479#endif
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001480 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001481}
1482
Howard Hinnant74279a52010-09-04 23:28:19 +00001483#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001484
Howard Hinnantc834c512011-11-29 18:15:50 +00001485template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001486void
Howard Hinnantc834c512011-11-29 18:15:50 +00001487promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001488{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001489#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001490 if (__state_ == nullptr)
1491 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001492#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001493 __state_->set_exception(__p);
1494}
1495
Howard Hinnantc834c512011-11-29 18:15:50 +00001496template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001497void
Howard Hinnantc834c512011-11-29 18:15:50 +00001498promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001499{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001500#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001501 if (__state_ == nullptr)
1502 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001503#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001504 __state_->set_value_at_thread_exit(__r);
1505}
1506
Howard Hinnant74279a52010-09-04 23:28:19 +00001507#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001508
Howard Hinnantc834c512011-11-29 18:15:50 +00001509template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001510void
Howard Hinnantc834c512011-11-29 18:15:50 +00001511promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001512{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001513#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001514 if (__state_ == nullptr)
1515 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001516#endif
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001517 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001518}
1519
Howard Hinnant74279a52010-09-04 23:28:19 +00001520#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001521
Howard Hinnantc834c512011-11-29 18:15:50 +00001522template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001523void
Howard Hinnantc834c512011-11-29 18:15:50 +00001524promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001525{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001526#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001527 if (__state_ == nullptr)
1528 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001529#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001530 __state_->set_exception_at_thread_exit(__p);
1531}
1532
1533// promise<R&>
1534
Howard Hinnantc834c512011-11-29 18:15:50 +00001535template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001536class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001537{
Howard Hinnantc834c512011-11-29 18:15:50 +00001538 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001539
Howard Hinnant684902d2010-09-22 14:16:26 +00001540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001541 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001542
1543 template <class> friend class packaged_task;
1544
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001545public:
1546 promise();
1547 template <class _Allocator>
1548 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001549#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001551 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001552 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1553 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001554#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001555private:
1556 promise(const promise& __rhs);
1557public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001558#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001559 ~promise();
1560
1561 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001562#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001564 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001565 {
1566 promise(std::move(__rhs)).swap(*this);
1567 return *this;
1568 }
1569 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001570#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001571private:
1572 promise& operator=(const promise& __rhs);
1573public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001574#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001575 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001576 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001577
1578 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001579 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001580
1581 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001582 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001583 void set_exception(exception_ptr __p);
1584
1585 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001586 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001587 void set_exception_at_thread_exit(exception_ptr __p);
1588};
1589
Howard Hinnantc834c512011-11-29 18:15:50 +00001590template <class _Rp>
1591promise<_Rp&>::promise()
1592 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001593{
1594}
1595
Howard Hinnantc834c512011-11-29 18:15:50 +00001596template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001597template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001598promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001599{
Eric Fiselier0d109272014-10-23 06:24:45 +00001600 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1601 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001602 typedef __allocator_destructor<_A2> _D2;
1603 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001604 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1605 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1606 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001607}
1608
Howard Hinnantc834c512011-11-29 18:15:50 +00001609template <class _Rp>
1610promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001611{
1612 if (__state_)
1613 {
1614 if (!__state_->__has_value() && __state_->use_count() > 1)
1615 __state_->set_exception(make_exception_ptr(
1616 future_error(make_error_code(future_errc::broken_promise))
1617 ));
1618 __state_->__release_shared();
1619 }
1620}
1621
Howard Hinnantc834c512011-11-29 18:15:50 +00001622template <class _Rp>
1623future<_Rp&>
1624promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001625{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001626#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001627 if (__state_ == nullptr)
1628 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001629#endif
Howard Hinnantc834c512011-11-29 18:15:50 +00001630 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001631}
1632
Howard Hinnantc834c512011-11-29 18:15:50 +00001633template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001634void
Howard Hinnantc834c512011-11-29 18:15:50 +00001635promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001636{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001637#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001638 if (__state_ == nullptr)
1639 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001640#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001641 __state_->set_value(__r);
1642}
1643
Howard Hinnantc834c512011-11-29 18:15:50 +00001644template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001645void
Howard Hinnantc834c512011-11-29 18:15:50 +00001646promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001647{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001648#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001649 if (__state_ == nullptr)
1650 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001651#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001652 __state_->set_exception(__p);
1653}
1654
Howard Hinnantc834c512011-11-29 18:15:50 +00001655template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001656void
Howard Hinnantc834c512011-11-29 18:15:50 +00001657promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001658{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001659#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001660 if (__state_ == nullptr)
1661 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001662#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001663 __state_->set_value_at_thread_exit(__r);
1664}
1665
Howard Hinnantc834c512011-11-29 18:15:50 +00001666template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001667void
Howard Hinnantc834c512011-11-29 18:15:50 +00001668promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001669{
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001670#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001671 if (__state_ == nullptr)
1672 throw future_error(make_error_code(future_errc::no_state));
Howard Hinnant83e6aad2011-07-13 16:00:50 +00001673#endif
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001674 __state_->set_exception_at_thread_exit(__p);
1675}
1676
1677// promise<void>
1678
1679template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00001680class _LIBCPP_TYPE_VIS promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001681{
1682 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001683
Howard Hinnant684902d2010-09-22 14:16:26 +00001684 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001685 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001686
1687 template <class> friend class packaged_task;
1688
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001689public:
1690 promise();
1691 template <class _Allocator>
1692 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001693#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001694 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001695 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001696 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1697 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001698#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001699private:
1700 promise(const promise& __rhs);
1701public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001702#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001703 ~promise();
1704
1705 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001706#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001707 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001708 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001709 {
1710 promise(std::move(__rhs)).swap(*this);
1711 return *this;
1712 }
1713 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001714#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001715private:
1716 promise& operator=(const promise& __rhs);
1717public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001718#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001720 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001721
1722 // retrieving the result
1723 future<void> get_future();
1724
1725 // setting the result
1726 void set_value();
1727 void set_exception(exception_ptr __p);
1728
1729 // setting the result with deferred notification
1730 void set_value_at_thread_exit();
1731 void set_exception_at_thread_exit(exception_ptr __p);
1732};
1733
1734template <class _Alloc>
1735promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1736{
Eric Fiselier0d109272014-10-23 06:24:45 +00001737 typedef __assoc_sub_state_alloc<_Alloc> _State;
1738 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001739 typedef __allocator_destructor<_A2> _D2;
1740 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001741 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1742 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1743 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001744}
1745
Howard Hinnantc834c512011-11-29 18:15:50 +00001746template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001747inline _LIBCPP_INLINE_VISIBILITY
1748void
Howard Hinnant22448042012-07-21 17:46:55 +00001749swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001750{
1751 __x.swap(__y);
1752}
1753
Howard Hinnantc834c512011-11-29 18:15:50 +00001754template <class _Rp, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00001755 struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001756 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001757
Howard Hinnantccdd2032010-08-30 18:46:21 +00001758#ifndef _LIBCPP_HAS_NO_VARIADICS
1759
1760// packaged_task
1761
1762template<class _Fp> class __packaged_task_base;
1763
Howard Hinnantc834c512011-11-29 18:15:50 +00001764template<class _Rp, class ..._ArgTypes>
1765class __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001766{
1767 __packaged_task_base(const __packaged_task_base&);
1768 __packaged_task_base& operator=(const __packaged_task_base&);
1769public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001770 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001771 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001773 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001774 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001775 virtual void destroy() = 0;
1776 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001777 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001778};
1779
1780template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1781
Howard Hinnantc834c512011-11-29 18:15:50 +00001782template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1783class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
1784 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001785{
Howard Hinnantc834c512011-11-29 18:15:50 +00001786 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001787public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001788 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001789 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001790 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001791 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001792 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001793 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001794 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001795 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001796 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001797 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001798 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001799 virtual void destroy();
1800 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001801 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001802};
1803
Howard Hinnantc834c512011-11-29 18:15:50 +00001804template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001805void
Howard Hinnantc834c512011-11-29 18:15:50 +00001806__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001807 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001808{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001809 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001810}
1811
Howard Hinnantc834c512011-11-29 18:15:50 +00001812template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001813void
Howard Hinnantc834c512011-11-29 18:15:50 +00001814__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001815{
Howard Hinnantc834c512011-11-29 18:15:50 +00001816 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001817}
1818
Howard Hinnantc834c512011-11-29 18:15:50 +00001819template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001820void
Howard Hinnantc834c512011-11-29 18:15:50 +00001821__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001822{
Eric Fiselier0d109272014-10-23 06:24:45 +00001823 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1824 typedef allocator_traits<_Ap> _ATraits;
1825 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001826 _Ap __a(__f_.second());
1827 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001828 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001829}
1830
Howard Hinnantc834c512011-11-29 18:15:50 +00001831template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1832_Rp
1833__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001834{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001835 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001836}
1837
Howard Hinnant944510a2011-06-14 19:58:17 +00001838template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001839
Howard Hinnantc834c512011-11-29 18:15:50 +00001840template<class _Rp, class ..._ArgTypes>
1841class __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001842{
Howard Hinnantc834c512011-11-29 18:15:50 +00001843 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001844 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001845 __base* __f_;
1846
1847public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001848 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001849
1850 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001851 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001852 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001853 template<class _Fp>
1854 __packaged_task_function(_Fp&& __f);
1855 template<class _Fp, class _Alloc>
1856 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001857
Howard Hinnant22448042012-07-21 17:46:55 +00001858 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1859 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001860
1861 __packaged_task_function(const __packaged_task_function&) = delete;
1862 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1863
1864 ~__packaged_task_function();
1865
Howard Hinnant22448042012-07-21 17:46:55 +00001866 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001867
Howard Hinnantc834c512011-11-29 18:15:50 +00001868 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001869};
1870
Howard Hinnantc834c512011-11-29 18:15:50 +00001871template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001872__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001873{
1874 if (__f.__f_ == nullptr)
1875 __f_ = nullptr;
1876 else if (__f.__f_ == (__base*)&__f.__buf_)
1877 {
1878 __f_ = (__base*)&__buf_;
1879 __f.__f_->__move_to(__f_);
1880 }
1881 else
1882 {
1883 __f_ = __f.__f_;
1884 __f.__f_ = nullptr;
1885 }
1886}
1887
Howard Hinnantc834c512011-11-29 18:15:50 +00001888template<class _Rp, class ..._ArgTypes>
1889template <class _Fp>
1890__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001891 : __f_(nullptr)
1892{
Marshall Clow733d60e2014-04-07 13:32:26 +00001893 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001894 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001895 if (sizeof(_FF) <= sizeof(__buf_))
1896 {
1897 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001898 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001899 }
1900 else
1901 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001902 typedef allocator<_FF> _Ap;
1903 _Ap __a;
1904 typedef __allocator_destructor<_Ap> _Dp;
1905 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1906 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001907 __f_ = __hold.release();
1908 }
1909}
1910
Howard Hinnantc834c512011-11-29 18:15:50 +00001911template<class _Rp, class ..._ArgTypes>
1912template <class _Fp, class _Alloc>
1913__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1914 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001915 : __f_(nullptr)
1916{
Marshall Clow733d60e2014-04-07 13:32:26 +00001917 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001918 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001919 if (sizeof(_FF) <= sizeof(__buf_))
1920 {
1921 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001922 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001923 }
1924 else
1925 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001926 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001927 _Ap __a(__a0);
1928 typedef __allocator_destructor<_Ap> _Dp;
1929 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001930 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1931 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1932 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001933 }
1934}
1935
Howard Hinnantc834c512011-11-29 18:15:50 +00001936template<class _Rp, class ..._ArgTypes>
1937__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001938__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001939{
1940 if (__f_ == (__base*)&__buf_)
1941 __f_->destroy();
1942 else if (__f_)
1943 __f_->destroy_deallocate();
1944 __f_ = nullptr;
1945 if (__f.__f_ == nullptr)
1946 __f_ = nullptr;
1947 else if (__f.__f_ == (__base*)&__f.__buf_)
1948 {
1949 __f_ = (__base*)&__buf_;
1950 __f.__f_->__move_to(__f_);
1951 }
1952 else
1953 {
1954 __f_ = __f.__f_;
1955 __f.__f_ = nullptr;
1956 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001957 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001958}
1959
Howard Hinnantc834c512011-11-29 18:15:50 +00001960template<class _Rp, class ..._ArgTypes>
1961__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001962{
1963 if (__f_ == (__base*)&__buf_)
1964 __f_->destroy();
1965 else if (__f_)
1966 __f_->destroy_deallocate();
1967}
1968
Howard Hinnantc834c512011-11-29 18:15:50 +00001969template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001970void
Howard Hinnant22448042012-07-21 17:46:55 +00001971__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001972{
1973 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1974 {
1975 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1976 __base* __t = (__base*)&__tempbuf;
1977 __f_->__move_to(__t);
1978 __f_->destroy();
1979 __f_ = nullptr;
1980 __f.__f_->__move_to((__base*)&__buf_);
1981 __f.__f_->destroy();
1982 __f.__f_ = nullptr;
1983 __f_ = (__base*)&__buf_;
1984 __t->__move_to((__base*)&__f.__buf_);
1985 __t->destroy();
1986 __f.__f_ = (__base*)&__f.__buf_;
1987 }
1988 else if (__f_ == (__base*)&__buf_)
1989 {
1990 __f_->__move_to((__base*)&__f.__buf_);
1991 __f_->destroy();
1992 __f_ = __f.__f_;
1993 __f.__f_ = (__base*)&__f.__buf_;
1994 }
1995 else if (__f.__f_ == (__base*)&__f.__buf_)
1996 {
1997 __f.__f_->__move_to((__base*)&__buf_);
1998 __f.__f_->destroy();
1999 __f.__f_ = __f_;
2000 __f_ = (__base*)&__buf_;
2001 }
2002 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002003 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002004}
2005
Howard Hinnantc834c512011-11-29 18:15:50 +00002006template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002007inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002008_Rp
2009__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00002010{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002011 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002012}
2013
Howard Hinnantc834c512011-11-29 18:15:50 +00002014template<class _Rp, class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002015class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002016{
2017public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002018 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002019
2020private:
2021 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2022 promise<result_type> __p_;
2023
2024public:
2025 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002026 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002027 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002028 template <class _Fp,
2029 class = typename enable_if
2030 <
2031 !is_same<
2032 typename decay<_Fp>::type,
2033 packaged_task
2034 >::value
2035 >::type
2036 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002037 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002038 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002039 template <class _Fp, class _Allocator,
2040 class = typename enable_if
2041 <
2042 !is_same<
2043 typename decay<_Fp>::type,
2044 packaged_task
2045 >::value
2046 >::type
2047 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002049 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2050 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002051 __p_(allocator_arg, __a) {}
2052 // ~packaged_task() = default;
2053
2054 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002055 packaged_task(const packaged_task&) = delete;
2056 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002057
2058 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002059 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002060 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002061 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002063 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002064 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002065 __f_ = _VSTD::move(__other.__f_);
2066 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002067 return *this;
2068 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002069 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002070 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002071 {
2072 __f_.swap(__other.__f_);
2073 __p_.swap(__other.__p_);
2074 }
2075
Howard Hinnant684902d2010-09-22 14:16:26 +00002076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002077 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002078
2079 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002080 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081 future<result_type> get_future() {return __p_.get_future();}
2082
2083 // execution
2084 void operator()(_ArgTypes... __args);
2085 void make_ready_at_thread_exit(_ArgTypes... __args);
2086
2087 void reset();
2088};
2089
Howard Hinnantc834c512011-11-29 18:15:50 +00002090template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002091void
Howard Hinnantc834c512011-11-29 18:15:50 +00002092packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002093{
2094#ifndef _LIBCPP_NO_EXCEPTIONS
2095 if (__p_.__state_ == nullptr)
2096 throw future_error(make_error_code(future_errc::no_state));
2097 if (__p_.__state_->__has_value())
2098 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2099 try
2100 {
2101#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002102 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002103#ifndef _LIBCPP_NO_EXCEPTIONS
2104 }
2105 catch (...)
2106 {
2107 __p_.set_exception(current_exception());
2108 }
2109#endif // _LIBCPP_NO_EXCEPTIONS
2110}
2111
Howard Hinnantc834c512011-11-29 18:15:50 +00002112template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002113void
Howard Hinnantc834c512011-11-29 18:15:50 +00002114packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002115{
2116#ifndef _LIBCPP_NO_EXCEPTIONS
2117 if (__p_.__state_ == nullptr)
2118 throw future_error(make_error_code(future_errc::no_state));
2119 if (__p_.__state_->__has_value())
2120 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2121 try
2122 {
2123#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002124 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002125#ifndef _LIBCPP_NO_EXCEPTIONS
2126 }
2127 catch (...)
2128 {
2129 __p_.set_exception_at_thread_exit(current_exception());
2130 }
2131#endif // _LIBCPP_NO_EXCEPTIONS
2132}
2133
Howard Hinnantc834c512011-11-29 18:15:50 +00002134template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002135void
Howard Hinnantc834c512011-11-29 18:15:50 +00002136packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002137{
2138#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002139 if (!valid())
Howard Hinnantccdd2032010-08-30 18:46:21 +00002140 throw future_error(make_error_code(future_errc::no_state));
2141#endif // _LIBCPP_NO_EXCEPTIONS
2142 __p_ = promise<result_type>();
2143}
2144
2145template<class ..._ArgTypes>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002146class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002147{
2148public:
2149 typedef void result_type;
2150
2151private:
2152 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2153 promise<result_type> __p_;
2154
2155public:
2156 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002157 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002158 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002159 template <class _Fp,
2160 class = typename enable_if
2161 <
2162 !is_same<
2163 typename decay<_Fp>::type,
2164 packaged_task
2165 >::value
2166 >::type
2167 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002168 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002169 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002170 template <class _Fp, class _Allocator,
2171 class = typename enable_if
2172 <
2173 !is_same<
2174 typename decay<_Fp>::type,
2175 packaged_task
2176 >::value
2177 >::type
2178 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002179 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002180 explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2181 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
Howard Hinnantccdd2032010-08-30 18:46:21 +00002182 __p_(allocator_arg, __a) {}
2183 // ~packaged_task() = default;
2184
2185 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002186 packaged_task(const packaged_task&) = delete;
2187 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002188
2189 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002190 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002191 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002192 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002193 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002194 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002195 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002196 __f_ = _VSTD::move(__other.__f_);
2197 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002198 return *this;
2199 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002200 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002201 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002202 {
2203 __f_.swap(__other.__f_);
2204 __p_.swap(__other.__p_);
2205 }
2206
Howard Hinnant684902d2010-09-22 14:16:26 +00002207 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002208 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002209
2210 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002212 future<result_type> get_future() {return __p_.get_future();}
2213
2214 // execution
2215 void operator()(_ArgTypes... __args);
2216 void make_ready_at_thread_exit(_ArgTypes... __args);
2217
2218 void reset();
2219};
2220
2221template<class ..._ArgTypes>
2222void
2223packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2224{
2225#ifndef _LIBCPP_NO_EXCEPTIONS
2226 if (__p_.__state_ == nullptr)
2227 throw future_error(make_error_code(future_errc::no_state));
2228 if (__p_.__state_->__has_value())
2229 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2230 try
2231 {
2232#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002233 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002234 __p_.set_value();
2235#ifndef _LIBCPP_NO_EXCEPTIONS
2236 }
2237 catch (...)
2238 {
2239 __p_.set_exception(current_exception());
2240 }
2241#endif // _LIBCPP_NO_EXCEPTIONS
2242}
2243
2244template<class ..._ArgTypes>
2245void
2246packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2247{
2248#ifndef _LIBCPP_NO_EXCEPTIONS
2249 if (__p_.__state_ == nullptr)
2250 throw future_error(make_error_code(future_errc::no_state));
2251 if (__p_.__state_->__has_value())
2252 throw future_error(make_error_code(future_errc::promise_already_satisfied));
2253 try
2254 {
2255#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002256 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002257 __p_.set_value_at_thread_exit();
2258#ifndef _LIBCPP_NO_EXCEPTIONS
2259 }
2260 catch (...)
2261 {
2262 __p_.set_exception_at_thread_exit(current_exception());
2263 }
2264#endif // _LIBCPP_NO_EXCEPTIONS
2265}
2266
2267template<class ..._ArgTypes>
2268void
2269packaged_task<void(_ArgTypes...)>::reset()
2270{
2271#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002272 if (!valid())
Howard Hinnantccdd2032010-08-30 18:46:21 +00002273 throw future_error(make_error_code(future_errc::no_state));
2274#endif // _LIBCPP_NO_EXCEPTIONS
2275 __p_ = promise<result_type>();
2276}
2277
2278template <class _Callable>
2279inline _LIBCPP_INLINE_VISIBILITY
2280void
Howard Hinnant22448042012-07-21 17:46:55 +00002281swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002282{
2283 __x.swap(__y);
2284}
2285
2286template <class _Callable, class _Alloc>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002287struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00002288 : public true_type {};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002289
Howard Hinnantc834c512011-11-29 18:15:50 +00002290template <class _Rp, class _Fp>
2291future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002292#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002293__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002294#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002295__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002296#endif
2297{
Howard Hinnantc834c512011-11-29 18:15:50 +00002298 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2299 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2300 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002301}
2302
Howard Hinnantc834c512011-11-29 18:15:50 +00002303template <class _Rp, class _Fp>
2304future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002305#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002306__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002307#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002308__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002309#endif
2310{
Howard Hinnantc834c512011-11-29 18:15:50 +00002311 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2312 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2313 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2314 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002315}
2316
Howard Hinnantc834c512011-11-29 18:15:50 +00002317template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002318class __async_func
2319{
Howard Hinnantc834c512011-11-29 18:15:50 +00002320 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002321
2322public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002323 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002324
2325 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002326 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002327 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002328
2329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002330 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002331
Howard Hinnantc834c512011-11-29 18:15:50 +00002332 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002333 {
2334 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2335 return __execute(_Index());
2336 }
2337private:
2338 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002339 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002340 __execute(__tuple_indices<_Indices...>)
2341 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002342 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002343 }
2344};
2345
Marshall Clowd56a5b62013-11-03 22:06:53 +00002346inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002347{ return (int(__policy) & int(__value)) != 0; }
2348
Howard Hinnantc834c512011-11-29 18:15:50 +00002349template <class _Fp, class... _Args>
2350future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2351async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002352{
Howard Hinnantc834c512011-11-29 18:15:50 +00002353 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2354 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002355
2356#ifndef _LIBCPP_NO_EXCEPTIONS
2357 try
2358 {
2359#endif
2360 if (__does_policy_contain(__policy, launch::async))
2361 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002362 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002363#ifndef _LIBCPP_NO_EXCEPTIONS
2364 }
2365 catch ( ... ) { if (__policy == launch::async) throw ; }
2366#endif
2367
2368 if (__does_policy_contain(__policy, launch::deferred))
2369 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002370 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002371 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002372}
2373
Howard Hinnantc834c512011-11-29 18:15:50 +00002374template <class _Fp, class... _Args>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002375inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002376future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2377async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002378{
Howard Hinnantc834c512011-11-29 18:15:50 +00002379 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002380 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002381}
2382
2383#endif // _LIBCPP_HAS_NO_VARIADICS
2384
Howard Hinnante6a10852010-09-03 21:46:37 +00002385// shared_future
2386
Howard Hinnantc834c512011-11-29 18:15:50 +00002387template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002388class _LIBCPP_TYPE_VIS_ONLY shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002389{
Howard Hinnantc834c512011-11-29 18:15:50 +00002390 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002391
2392public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002393 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002394 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002396 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2397 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002398#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002400 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002401 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002403 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002404 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002405#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002406 ~shared_future();
2407 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002408#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002409 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002410 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002411 {
2412 shared_future(std::move(__rhs)).swap(*this);
2413 return *this;
2414 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002415#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002416
2417 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002418 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002419 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002420
Howard Hinnant684902d2010-09-22 14:16:26 +00002421 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002422 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002423
2424 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002425 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002426 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002427
Howard Hinnant684902d2010-09-22 14:16:26 +00002428 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002429 void wait() const {__state_->wait();}
2430 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002432 future_status
2433 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2434 {return __state_->wait_for(__rel_time);}
2435 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002436 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002437 future_status
2438 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2439 {return __state_->wait_until(__abs_time);}
2440};
2441
Howard Hinnantc834c512011-11-29 18:15:50 +00002442template <class _Rp>
2443shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002444{
2445 if (__state_)
2446 __state_->__release_shared();
2447}
2448
Howard Hinnantc834c512011-11-29 18:15:50 +00002449template <class _Rp>
2450shared_future<_Rp>&
2451shared_future<_Rp>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002452{
2453 if (__rhs.__state_)
2454 __rhs.__state_->__add_shared();
2455 if (__state_)
2456 __state_->__release_shared();
2457 __state_ = __rhs.__state_;
2458 return *this;
2459}
2460
Howard Hinnantc834c512011-11-29 18:15:50 +00002461template <class _Rp>
Howard Hinnanta37d3cf2013-08-12 18:38:34 +00002462class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002463{
Howard Hinnantc834c512011-11-29 18:15:50 +00002464 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002465
2466public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002467 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002468 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002469 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002470 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2471 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002472#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002474 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002475 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002477 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002478 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002479#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002480 ~shared_future();
2481 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002482#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002483 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002484 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002485 {
2486 shared_future(std::move(__rhs)).swap(*this);
2487 return *this;
2488 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002489#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002490
2491 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002493 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002494
Howard Hinnant684902d2010-09-22 14:16:26 +00002495 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002496 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002497
2498 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002499 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002500 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002501
Howard Hinnant684902d2010-09-22 14:16:26 +00002502 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002503 void wait() const {__state_->wait();}
2504 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002505 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002506 future_status
2507 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2508 {return __state_->wait_for(__rel_time);}
2509 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002511 future_status
2512 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2513 {return __state_->wait_until(__abs_time);}
2514};
2515
Howard Hinnantc834c512011-11-29 18:15:50 +00002516template <class _Rp>
2517shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002518{
2519 if (__state_)
2520 __state_->__release_shared();
2521}
2522
Howard Hinnantc834c512011-11-29 18:15:50 +00002523template <class _Rp>
2524shared_future<_Rp&>&
2525shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002526{
2527 if (__rhs.__state_)
2528 __rhs.__state_->__add_shared();
2529 if (__state_)
2530 __state_->__release_shared();
2531 __state_ = __rhs.__state_;
2532 return *this;
2533}
2534
2535template <>
Howard Hinnant8331b762013-03-06 23:30:19 +00002536class _LIBCPP_TYPE_VIS shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002537{
2538 __assoc_sub_state* __state_;
2539
2540public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002541 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002542 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002543 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002544 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2545 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002546#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002548 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002549 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002551 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002552 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002553#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002554 ~shared_future();
2555 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002556#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002557 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002558 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002559 {
2560 shared_future(std::move(__rhs)).swap(*this);
2561 return *this;
2562 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002563#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002564
2565 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002567 void get() const {__state_->copy();}
2568
Howard Hinnant684902d2010-09-22 14:16:26 +00002569 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002570 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002571
2572 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002573 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002574 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002575
Howard Hinnant684902d2010-09-22 14:16:26 +00002576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002577 void wait() const {__state_->wait();}
2578 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002580 future_status
2581 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2582 {return __state_->wait_for(__rel_time);}
2583 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002585 future_status
2586 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2587 {return __state_->wait_until(__abs_time);}
2588};
2589
Howard Hinnantc834c512011-11-29 18:15:50 +00002590template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002591inline _LIBCPP_INLINE_VISIBILITY
2592void
Howard Hinnant22448042012-07-21 17:46:55 +00002593swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002594{
2595 __x.swap(__y);
2596}
2597
Howard Hinnantc834c512011-11-29 18:15:50 +00002598template <class _Rp>
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002599inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002600shared_future<_Rp>
2601future<_Rp>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002602{
Howard Hinnantc834c512011-11-29 18:15:50 +00002603 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002604}
2605
Howard Hinnantc834c512011-11-29 18:15:50 +00002606template <class _Rp>
Howard Hinnante6a10852010-09-03 21:46:37 +00002607inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002608shared_future<_Rp&>
2609future<_Rp&>::share()
Howard Hinnante6a10852010-09-03 21:46:37 +00002610{
Howard Hinnantc834c512011-11-29 18:15:50 +00002611 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002612}
2613
Howard Hinnante65e8e32010-12-02 16:45:21 +00002614#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2615
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002616inline _LIBCPP_INLINE_VISIBILITY
2617shared_future<void>
2618future<void>::share()
2619{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002620 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002621}
2622
Howard Hinnante65e8e32010-12-02 16:45:21 +00002623#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2624
Howard Hinnantc51e1022010-05-11 19:42:16 +00002625_LIBCPP_END_NAMESPACE_STD
2626
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002627#endif // !_LIBCPP_HAS_NO_THREADS
2628
Howard Hinnantc51e1022010-05-11 19:42:16 +00002629#endif // _LIBCPP_FUTURE