blob: 24396e72ac457239cda7b48e13b486619f252a6d [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- future -----------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantc51e1022010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FUTURE
11#define _LIBCPP_FUTURE
12
13/*
14 future synopsis
15
16namespace std
17{
18
19enum class future_errc
20{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000021 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +000022 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +000023 no_state,
24 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +000025};
26
27enum class launch
28{
Howard Hinnante3df4ea2010-11-23 18:33:54 +000029 async = 1,
30 deferred = 2,
31 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +000032};
33
34enum class future_status
35{
36 ready,
37 timeout,
38 deferred
39};
40
41template <> struct is_error_code_enum<future_errc> : public true_type { };
Howard Hinnant22448042012-07-21 17:46:55 +000042error_code make_error_code(future_errc e) noexcept;
43error_condition make_error_condition(future_errc e) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000044
Howard Hinnant22448042012-07-21 17:46:55 +000045const error_category& future_category() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000046
47class future_error
48 : public logic_error
49{
50public:
51 future_error(error_code ec); // exposition only
Marshall Clowd4a669c2016-11-14 18:56:24 +000052 explicit future_error(future_errc); // C++17
Howard Hinnant22448042012-07-21 17:46:55 +000053 const error_code& code() const noexcept;
54 const char* what() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000055};
56
57template <class R>
58class promise
59{
60public:
61 promise();
62 template <class Allocator>
63 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000064 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000065 promise(const promise& rhs) = delete;
66 ~promise();
67
68 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000069 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000070 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +000071 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000072
73 // retrieving the result
74 future<R> get_future();
75
76 // setting the result
77 void set_value(const R& r);
78 void set_value(R&& r);
79 void set_exception(exception_ptr p);
80
81 // setting the result with deferred notification
82 void set_value_at_thread_exit(const R& r);
83 void set_value_at_thread_exit(R&& r);
84 void set_exception_at_thread_exit(exception_ptr p);
85};
86
87template <class R>
88class promise<R&>
89{
90public:
91 promise();
92 template <class Allocator>
93 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +000094 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +000095 promise(const promise& rhs) = delete;
96 ~promise();
97
98 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +000099 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000100 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000101 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000102
103 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000104 future<R&> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000105
106 // setting the result
107 void set_value(R& r);
108 void set_exception(exception_ptr p);
109
110 // setting the result with deferred notification
111 void set_value_at_thread_exit(R&);
112 void set_exception_at_thread_exit(exception_ptr p);
113};
114
115template <>
116class promise<void>
117{
118public:
119 promise();
120 template <class Allocator>
121 promise(allocator_arg_t, const Allocator& a);
Howard Hinnant22448042012-07-21 17:46:55 +0000122 promise(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000123 promise(const promise& rhs) = delete;
124 ~promise();
125
126 // assignment
Howard Hinnant22448042012-07-21 17:46:55 +0000127 promise& operator=(promise&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000128 promise& operator=(const promise& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000129 void swap(promise& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000130
131 // retrieving the result
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000132 future<void> get_future();
Howard Hinnantc51e1022010-05-11 19:42:16 +0000133
134 // setting the result
135 void set_value();
136 void set_exception(exception_ptr p);
137
138 // setting the result with deferred notification
139 void set_value_at_thread_exit();
140 void set_exception_at_thread_exit(exception_ptr p);
141};
142
Howard Hinnant22448042012-07-21 17:46:55 +0000143template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000144
145template <class R, class Alloc>
146 struct uses_allocator<promise<R>, Alloc> : public true_type {};
147
148template <class R>
149class future
150{
151public:
Howard Hinnant22448042012-07-21 17:46:55 +0000152 future() noexcept;
153 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000154 future(const future& rhs) = delete;
155 ~future();
156 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000157 future& operator=(future&&) noexcept;
Marshall Clow597881d2017-01-25 20:14:03 +0000158 shared_future<R> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000159
160 // retrieving the value
161 R get();
162
163 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000164 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000165
166 void wait() const;
167 template <class Rep, class Period>
168 future_status
169 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
170 template <class Clock, class Duration>
171 future_status
172 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
173};
174
175template <class R>
176class future<R&>
177{
178public:
Howard Hinnant22448042012-07-21 17:46:55 +0000179 future() noexcept;
180 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000181 future(const future& rhs) = delete;
182 ~future();
183 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000184 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000185 shared_future<R&> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000186
187 // retrieving the value
188 R& get();
189
190 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000191 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000192
193 void wait() const;
194 template <class Rep, class Period>
195 future_status
196 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
197 template <class Clock, class Duration>
198 future_status
199 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
200};
201
202template <>
203class future<void>
204{
205public:
Howard Hinnant22448042012-07-21 17:46:55 +0000206 future() noexcept;
207 future(future&&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000208 future(const future& rhs) = delete;
209 ~future();
210 future& operator=(const future& rhs) = delete;
Howard Hinnant22448042012-07-21 17:46:55 +0000211 future& operator=(future&&) noexcept;
Marshall Clow79e02112017-01-24 23:28:25 +0000212 shared_future<void> share() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000213
214 // retrieving the value
215 void get();
216
217 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000218 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000219
220 void wait() const;
221 template <class Rep, class Period>
222 future_status
223 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
224 template <class Clock, class Duration>
225 future_status
226 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
227};
228
229template <class R>
230class shared_future
231{
232public:
Howard Hinnant22448042012-07-21 17:46:55 +0000233 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000234 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000235 shared_future(future<R>&&) noexcept;
236 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000237 ~shared_future();
238 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000239 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000240
241 // retrieving the value
242 const R& get() const;
243
244 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000245 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246
247 void wait() const;
248 template <class Rep, class Period>
249 future_status
250 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
251 template <class Clock, class Duration>
252 future_status
253 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
254};
255
256template <class R>
257class shared_future<R&>
258{
259public:
Howard Hinnant22448042012-07-21 17:46:55 +0000260 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000261 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000262 shared_future(future<R&>&&) noexcept;
263 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264 ~shared_future();
265 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000266 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000267
268 // retrieving the value
269 R& get() const;
270
271 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000272 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000273
274 void wait() const;
275 template <class Rep, class Period>
276 future_status
277 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
278 template <class Clock, class Duration>
279 future_status
280 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
281};
282
283template <>
284class shared_future<void>
285{
286public:
Howard Hinnant22448042012-07-21 17:46:55 +0000287 shared_future() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000288 shared_future(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000289 shared_future(future<void>&&) noexcept;
290 shared_future(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000291 ~shared_future();
292 shared_future& operator=(const shared_future& rhs);
Howard Hinnant22448042012-07-21 17:46:55 +0000293 shared_future& operator=(shared_future&& rhs) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000294
295 // retrieving the value
296 void get() const;
297
298 // functions to check state
Howard Hinnant22448042012-07-21 17:46:55 +0000299 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000300
301 void wait() const;
302 template <class Rep, class Period>
303 future_status
304 wait_for(const chrono::duration<Rep, Period>& rel_time) const;
305 template <class Clock, class Duration>
306 future_status
307 wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
308};
309
Howard Hinnantc51e1022010-05-11 19:42:16 +0000310template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000311 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000312 async(F&& f, Args&&... args);
313
314template <class F, class... Args>
Howard Hinnant15579d22013-09-21 18:17:23 +0000315 future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000316 async(launch policy, F&& f, Args&&... args);
317
Howard Hinnantc566dc32010-05-11 21:36:01 +0000318template <class> class packaged_task; // undefined
Howard Hinnantc51e1022010-05-11 19:42:16 +0000319
320template <class R, class... ArgTypes>
321class packaged_task<R(ArgTypes...)>
322{
323public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +0000324 typedef R result_type; // extension
Howard Hinnantc51e1022010-05-11 19:42:16 +0000325
326 // construction and destruction
Howard Hinnant22448042012-07-21 17:46:55 +0000327 packaged_task() noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000328 template <class F>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000329 explicit packaged_task(F&& f);
Marshall Clowa0a057e2017-11-27 20:47:54 +0000330 template <class F, class Allocator>
331 packaged_task(allocator_arg_t, const Allocator& a, F&& f);
Howard Hinnantc51e1022010-05-11 19:42:16 +0000332 ~packaged_task();
333
334 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +0000335 packaged_task(const packaged_task&) = delete;
336 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337
338 // move support
Howard Hinnant22448042012-07-21 17:46:55 +0000339 packaged_task(packaged_task&& other) noexcept;
340 packaged_task& operator=(packaged_task&& other) noexcept;
341 void swap(packaged_task& other) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000342
Howard Hinnant22448042012-07-21 17:46:55 +0000343 bool valid() const noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344
345 // result retrieval
346 future<R> get_future();
347
348 // execution
349 void operator()(ArgTypes... );
350 void make_ready_at_thread_exit(ArgTypes...);
351
352 void reset();
353};
354
355template <class R>
Howard Hinnant22448042012-07-21 17:46:55 +0000356 void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000357
Marshall Clowa0a057e2017-11-27 20:47:54 +0000358template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
359
Howard Hinnantc51e1022010-05-11 19:42:16 +0000360} // std
361
362*/
363
364#include <__config>
365#include <system_error>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000366#include <memory>
367#include <chrono>
368#include <exception>
Howard Hinnante6a10852010-09-03 21:46:37 +0000369#include <mutex>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000370#include <thread>
Howard Hinnantc51e1022010-05-11 19:42:16 +0000371
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000372#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000373#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000374#endif
Howard Hinnantc51e1022010-05-11 19:42:16 +0000375
Jonathan Roelofs067218a2014-09-05 20:28:44 +0000376#ifdef _LIBCPP_HAS_NO_THREADS
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000377#error <future> is not supported on this single threaded system
378#else // !_LIBCPP_HAS_NO_THREADS
379
Howard Hinnantc51e1022010-05-11 19:42:16 +0000380_LIBCPP_BEGIN_NAMESPACE_STD
381
382//enum class future_errc
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000383_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000384{
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000385 future_already_retrieved = 1,
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386 promise_already_satisfied,
Howard Hinnantf2fd64d2013-09-14 18:20:10 +0000387 no_state,
388 broken_promise
Howard Hinnantc51e1022010-05-11 19:42:16 +0000389};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000390_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000391
Howard Hinnant684902d2010-09-22 14:16:26 +0000392template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000393struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc> : public true_type {};
Howard Hinnant96803d92010-08-25 17:32:05 +0000394
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000395#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
396template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000397struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000398#endif
399
Howard Hinnantc51e1022010-05-11 19:42:16 +0000400//enum class launch
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000401_LIBCPP_DECLARE_STRONG_ENUM(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000402{
Howard Hinnante3df4ea2010-11-23 18:33:54 +0000403 async = 1,
404 deferred = 2,
405 any = async | deferred
Howard Hinnantc51e1022010-05-11 19:42:16 +0000406};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000407_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000408
Howard Hinnantda760a82013-06-29 18:38:17 +0000409#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
410
Eric Fiselier94d23cb2018-07-24 09:15:03 +0000411#ifdef _LIBCPP_UNDERLYING_TYPE
Howard Hinnantda760a82013-06-29 18:38:17 +0000412typedef underlying_type<launch>::type __launch_underlying_type;
413#else
414typedef int __launch_underlying_type;
415#endif
416
417inline _LIBCPP_INLINE_VISIBILITY
418_LIBCPP_CONSTEXPR
419launch
420operator&(launch __x, launch __y)
421{
422 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
423 static_cast<__launch_underlying_type>(__y));
424}
425
426inline _LIBCPP_INLINE_VISIBILITY
427_LIBCPP_CONSTEXPR
428launch
429operator|(launch __x, launch __y)
430{
431 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
432 static_cast<__launch_underlying_type>(__y));
433}
434
435inline _LIBCPP_INLINE_VISIBILITY
436_LIBCPP_CONSTEXPR
437launch
438operator^(launch __x, launch __y)
439{
440 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
441 static_cast<__launch_underlying_type>(__y));
442}
443
444inline _LIBCPP_INLINE_VISIBILITY
445_LIBCPP_CONSTEXPR
446launch
447operator~(launch __x)
448{
Howard Hinnant373d7602013-07-02 18:01:41 +0000449 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000450}
451
452inline _LIBCPP_INLINE_VISIBILITY
453launch&
454operator&=(launch& __x, launch __y)
455{
456 __x = __x & __y; return __x;
457}
458
459inline _LIBCPP_INLINE_VISIBILITY
460launch&
461operator|=(launch& __x, launch __y)
462{
463 __x = __x | __y; return __x;
464}
465
466inline _LIBCPP_INLINE_VISIBILITY
467launch&
468operator^=(launch& __x, launch __y)
469{
470 __x = __x ^ __y; return __x;
471}
472
473#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
474
Howard Hinnantc51e1022010-05-11 19:42:16 +0000475//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000476_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000477{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000478 ready,
479 timeout,
480 deferred
481};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000482_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000483
Howard Hinnant8331b762013-03-06 23:30:19 +0000484_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000485const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000486
487inline _LIBCPP_INLINE_VISIBILITY
488error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000489make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000490{
491 return error_code(static_cast<int>(__e), future_category());
492}
493
494inline _LIBCPP_INLINE_VISIBILITY
495error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000496make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000497{
498 return error_condition(static_cast<int>(__e), future_category());
499}
500
Mehdi Amini228053d2017-05-04 17:08:54 +0000501class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000502 : public logic_error
503{
504 error_code __ec_;
505public:
506 future_error(error_code __ec);
Marshall Clowd4a669c2016-11-14 18:56:24 +0000507#if _LIBCPP_STD_VERS > 14
508 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
509#endif
Howard Hinnant684902d2010-09-22 14:16:26 +0000510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000511 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000512
513 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000514};
515
Louis Dionne16fe2952018-07-11 23:14:33 +0000516_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000517#ifndef _LIBCPP_NO_EXCEPTIONS
518_LIBCPP_AVAILABILITY_FUTURE_ERROR
519#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000520void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000521{
522#ifndef _LIBCPP_NO_EXCEPTIONS
523 throw future_error(make_error_code(_Ev));
524#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000525 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000526 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000527#endif
528}
529
Mehdi Amini228053d2017-05-04 17:08:54 +0000530class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000531 : public __shared_count
532{
533protected:
534 exception_ptr __exception_;
535 mutable mutex __mut_;
536 mutable condition_variable __cv_;
537 unsigned __state_;
538
Howard Hinnant719bda32011-05-28 14:41:13 +0000539 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000540 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000541public:
542 enum
543 {
544 __constructed = 1,
545 __future_attached = 2,
546 ready = 4,
547 deferred = 8
548 };
549
Howard Hinnant684902d2010-09-22 14:16:26 +0000550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000551 __assoc_sub_state() : __state_(0) {}
552
Howard Hinnant684902d2010-09-22 14:16:26 +0000553 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000554 bool __has_value() const
555 {return (__state_ & __constructed) || (__exception_ != nullptr);}
556
Howard Hinnant684902d2010-09-22 14:16:26 +0000557 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000558 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000559 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000560 bool __has_future_attached = (__state_ & __future_attached) != 0;
561 if (__has_future_attached)
562 __throw_future_error(future_errc::future_already_retrieved);
563 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000564 __state_ |= __future_attached;
565 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000566
Howard Hinnant684902d2010-09-22 14:16:26 +0000567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000568 void __set_deferred() {__state_ |= deferred;}
569
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000570 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000571 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000572 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000573
574 void set_value();
575 void set_value_at_thread_exit();
576
577 void set_exception(exception_ptr __p);
578 void set_exception_at_thread_exit(exception_ptr __p);
579
580 void copy();
581
Howard Hinnantccdd2032010-08-30 18:46:21 +0000582 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000583 template <class _Rep, class _Period>
584 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000585 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000586 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
587 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000588 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000589 future_status
590 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000591
592 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000593};
594
Howard Hinnantf4712b92010-08-28 21:01:06 +0000595template <class _Clock, class _Duration>
596future_status
597__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
598{
599 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000600 if (__state_ & deferred)
601 return future_status::deferred;
602 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000603 __cv_.wait_until(__lk, __abs_time);
604 if (__state_ & ready)
605 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000606 return future_status::timeout;
607}
608
609template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000610inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000611future_status
612__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
613{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000614 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000615}
616
Howard Hinnantc834c512011-11-29 18:15:50 +0000617template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000618class _LIBCPP_AVAILABILITY_FUTURE __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000619 : public __assoc_sub_state
620{
621 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000622 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000623protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000624 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000625
Howard Hinnant719bda32011-05-28 14:41:13 +0000626 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000627public:
628
629 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000630#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000631 void set_value(_Arg&& __arg);
632#else
633 void set_value(_Arg& __arg);
634#endif
635
636 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000637#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000638 void set_value_at_thread_exit(_Arg&& __arg);
639#else
640 void set_value_at_thread_exit(_Arg& __arg);
641#endif
642
Howard Hinnantc834c512011-11-29 18:15:50 +0000643 _Rp move();
644 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000645};
646
Howard Hinnantc834c512011-11-29 18:15:50 +0000647template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000648void
Howard Hinnantc834c512011-11-29 18:15:50 +0000649__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000650{
651 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000652 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000653 delete this;
654}
655
Howard Hinnantc834c512011-11-29 18:15:50 +0000656template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000657template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000658_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000659void
Howard Hinnant74279a52010-09-04 23:28:19 +0000660#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000661__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000662#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000663__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000664#endif
665{
666 unique_lock<mutex> __lk(this->__mut_);
667 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000668 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000669 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000670 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000671 __cv_.notify_all();
672}
673
Howard Hinnantc834c512011-11-29 18:15:50 +0000674template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675template <class _Arg>
676void
Howard Hinnant74279a52010-09-04 23:28:19 +0000677#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000678__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000679#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000680__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000681#endif
682{
683 unique_lock<mutex> __lk(this->__mut_);
684 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000685 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000686 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000687 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000688 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000689}
690
Howard Hinnantc834c512011-11-29 18:15:50 +0000691template <class _Rp>
692_Rp
693__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000694{
695 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000696 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000697 if (this->__exception_ != nullptr)
698 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000699 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000700}
701
Howard Hinnantc834c512011-11-29 18:15:50 +0000702template <class _Rp>
703typename add_lvalue_reference<_Rp>::type
704__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000705{
706 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000707 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000708 if (this->__exception_ != nullptr)
709 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000710 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000711}
712
Howard Hinnantc834c512011-11-29 18:15:50 +0000713template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000714class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715 : public __assoc_sub_state
716{
717 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000718 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000719protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000720 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000721
Howard Hinnant719bda32011-05-28 14:41:13 +0000722 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000723public:
724
Howard Hinnantc834c512011-11-29 18:15:50 +0000725 void set_value(_Rp& __arg);
726 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000727
Howard Hinnantc834c512011-11-29 18:15:50 +0000728 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000729};
730
Howard Hinnantc834c512011-11-29 18:15:50 +0000731template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000732void
Howard Hinnantc834c512011-11-29 18:15:50 +0000733__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000734{
735 delete this;
736}
737
Howard Hinnantc834c512011-11-29 18:15:50 +0000738template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000739void
Howard Hinnantc834c512011-11-29 18:15:50 +0000740__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000741{
742 unique_lock<mutex> __lk(this->__mut_);
743 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000744 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000745 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000746 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000747 __cv_.notify_all();
748}
749
Howard Hinnantc834c512011-11-29 18:15:50 +0000750template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000751void
Howard Hinnantc834c512011-11-29 18:15:50 +0000752__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000753{
754 unique_lock<mutex> __lk(this->__mut_);
755 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000756 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000757 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000758 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000759 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000760}
761
Howard Hinnantc834c512011-11-29 18:15:50 +0000762template <class _Rp>
763_Rp&
764__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000765{
766 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000767 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000768 if (this->__exception_ != nullptr)
769 rethrow_exception(this->__exception_);
770 return *__value_;
771}
772
Howard Hinnantc834c512011-11-29 18:15:50 +0000773template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000774class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000775 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000776{
Howard Hinnantc834c512011-11-29 18:15:50 +0000777 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000778 _Alloc __alloc_;
779
Howard Hinnant719bda32011-05-28 14:41:13 +0000780 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000781public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000782 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000783 explicit __assoc_state_alloc(const _Alloc& __a)
784 : __alloc_(__a) {}
785};
786
Howard Hinnantc834c512011-11-29 18:15:50 +0000787template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000788void
Howard Hinnantc834c512011-11-29 18:15:50 +0000789__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000790{
791 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000792 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000793 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
794 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000795 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000796 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000797 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000798 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000799}
800
Howard Hinnantc834c512011-11-29 18:15:50 +0000801template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000802class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000803 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000804{
Howard Hinnantc834c512011-11-29 18:15:50 +0000805 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000806 _Alloc __alloc_;
807
Howard Hinnant719bda32011-05-28 14:41:13 +0000808 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000809public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000810 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000811 explicit __assoc_state_alloc(const _Alloc& __a)
812 : __alloc_(__a) {}
813};
814
Howard Hinnantc834c512011-11-29 18:15:50 +0000815template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000816void
Howard Hinnantc834c512011-11-29 18:15:50 +0000817__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000818{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000819 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
820 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000821 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000822 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000823 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000824 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000825}
826
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000827template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000828class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000829 : public __assoc_sub_state
830{
831 typedef __assoc_sub_state base;
832 _Alloc __alloc_;
833
Howard Hinnant719bda32011-05-28 14:41:13 +0000834 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000835public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000837 explicit __assoc_sub_state_alloc(const _Alloc& __a)
838 : __alloc_(__a) {}
839};
840
841template <class _Alloc>
842void
Howard Hinnant719bda32011-05-28 14:41:13 +0000843__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000844{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000845 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
846 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000847 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000848 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000849 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000850 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000851}
852
Howard Hinnantc834c512011-11-29 18:15:50 +0000853template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000854class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000855 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000856{
Howard Hinnantc834c512011-11-29 18:15:50 +0000857 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000858
Howard Hinnantc834c512011-11-29 18:15:50 +0000859 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000860
861public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000862#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000863 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000864 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000865#endif
866
867 virtual void __execute();
868};
869
Howard Hinnant74279a52010-09-04 23:28:19 +0000870#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000871
Howard Hinnantc834c512011-11-29 18:15:50 +0000872template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000873inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000874__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
875 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000876{
877 this->__set_deferred();
878}
879
Howard Hinnant74279a52010-09-04 23:28:19 +0000880#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000881
Howard Hinnantc834c512011-11-29 18:15:50 +0000882template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000883void
Howard Hinnantc834c512011-11-29 18:15:50 +0000884__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000885{
886#ifndef _LIBCPP_NO_EXCEPTIONS
887 try
888 {
889#endif // _LIBCPP_NO_EXCEPTIONS
890 this->set_value(__func_());
891#ifndef _LIBCPP_NO_EXCEPTIONS
892 }
893 catch (...)
894 {
895 this->set_exception(current_exception());
896 }
897#endif // _LIBCPP_NO_EXCEPTIONS
898}
899
Howard Hinnantc834c512011-11-29 18:15:50 +0000900template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000901class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000902 : public __assoc_sub_state
903{
904 typedef __assoc_sub_state base;
905
Howard Hinnantc834c512011-11-29 18:15:50 +0000906 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000907
908public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000909#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000910 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000911 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000912#endif
913
914 virtual void __execute();
915};
916
Howard Hinnant74279a52010-09-04 23:28:19 +0000917#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000918
Howard Hinnantc834c512011-11-29 18:15:50 +0000919template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000920inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000921__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
922 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000923{
924 this->__set_deferred();
925}
926
Howard Hinnant74279a52010-09-04 23:28:19 +0000927#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000928
Howard Hinnantc834c512011-11-29 18:15:50 +0000929template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000930void
Howard Hinnantc834c512011-11-29 18:15:50 +0000931__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000932{
933#ifndef _LIBCPP_NO_EXCEPTIONS
934 try
935 {
936#endif // _LIBCPP_NO_EXCEPTIONS
937 __func_();
938 this->set_value();
939#ifndef _LIBCPP_NO_EXCEPTIONS
940 }
941 catch (...)
942 {
943 this->set_exception(current_exception());
944 }
945#endif // _LIBCPP_NO_EXCEPTIONS
946}
947
Howard Hinnantc834c512011-11-29 18:15:50 +0000948template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000949class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000950 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000951{
Howard Hinnantc834c512011-11-29 18:15:50 +0000952 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000953
Howard Hinnantc834c512011-11-29 18:15:50 +0000954 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000955
Howard Hinnant719bda32011-05-28 14:41:13 +0000956 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000957public:
958#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000959 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000960 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000961#endif
962
963 virtual void __execute();
964};
965
966#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
967
Howard Hinnantc834c512011-11-29 18:15:50 +0000968template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000969inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000970__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
971 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000972{
973}
974
975#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
976
Howard Hinnantc834c512011-11-29 18:15:50 +0000977template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000978void
Howard Hinnantc834c512011-11-29 18:15:50 +0000979__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000980{
981#ifndef _LIBCPP_NO_EXCEPTIONS
982 try
983 {
984#endif // _LIBCPP_NO_EXCEPTIONS
985 this->set_value(__func_());
986#ifndef _LIBCPP_NO_EXCEPTIONS
987 }
988 catch (...)
989 {
990 this->set_exception(current_exception());
991 }
992#endif // _LIBCPP_NO_EXCEPTIONS
993}
994
Howard Hinnantc834c512011-11-29 18:15:50 +0000995template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000996void
Howard Hinnantc834c512011-11-29 18:15:50 +0000997__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000998{
999 this->wait();
1000 base::__on_zero_shared();
1001}
1002
Howard Hinnantc834c512011-11-29 18:15:50 +00001003template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001004class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001005 : public __assoc_sub_state
1006{
1007 typedef __assoc_sub_state base;
1008
Howard Hinnantc834c512011-11-29 18:15:50 +00001009 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001010
Howard Hinnant719bda32011-05-28 14:41:13 +00001011 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001012public:
1013#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001015 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001016#endif
1017
1018 virtual void __execute();
1019};
1020
1021#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1022
Howard Hinnantc834c512011-11-29 18:15:50 +00001023template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001024inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001025__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1026 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001027{
1028}
1029
1030#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1031
Howard Hinnantc834c512011-11-29 18:15:50 +00001032template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001033void
Howard Hinnantc834c512011-11-29 18:15:50 +00001034__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001035{
1036#ifndef _LIBCPP_NO_EXCEPTIONS
1037 try
1038 {
1039#endif // _LIBCPP_NO_EXCEPTIONS
1040 __func_();
1041 this->set_value();
1042#ifndef _LIBCPP_NO_EXCEPTIONS
1043 }
1044 catch (...)
1045 {
1046 this->set_exception(current_exception());
1047 }
1048#endif // _LIBCPP_NO_EXCEPTIONS
1049}
1050
Howard Hinnantc834c512011-11-29 18:15:50 +00001051template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001052void
Howard Hinnantc834c512011-11-29 18:15:50 +00001053__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001054{
1055 this->wait();
1056 base::__on_zero_shared();
1057}
1058
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001059template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1060template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001061
1062// future
1063
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001064template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001065
Howard Hinnantc834c512011-11-29 18:15:50 +00001066template <class _Rp, class _Fp>
1067future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001068#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001069__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001070#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001071__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001072#endif
1073
Howard Hinnantc834c512011-11-29 18:15:50 +00001074template <class _Rp, class _Fp>
1075future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001076#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001077__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001078#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001079__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001080#endif
1081
Howard Hinnantc834c512011-11-29 18:15:50 +00001082template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001083class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001084{
Howard Hinnantc834c512011-11-29 18:15:50 +00001085 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001086
Howard Hinnantc834c512011-11-29 18:15:50 +00001087 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001088
1089 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001090 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001091
Howard Hinnant74279a52010-09-04 23:28:19 +00001092#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001093 template <class _R1, class _Fp>
1094 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1095 template <class _R1, class _Fp>
1096 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001097#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001098 template <class _R1, class _Fp>
1099 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1100 template <class _R1, class _Fp>
1101 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001102#endif
1103
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001104public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001105 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001106 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001107#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001108 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001109 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001110 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1111 future(const future&) = delete;
1112 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001113 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001114 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001115 {
1116 future(std::move(__rhs)).swap(*this);
1117 return *this;
1118 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001119#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001120private:
1121 future(const future&);
1122 future& operator=(const future&);
1123public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001124#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001125 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001126 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001127 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001128
1129 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001130 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001131
Howard Hinnant684902d2010-09-22 14:16:26 +00001132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001133 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001134
1135 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001137 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001138
Howard Hinnant684902d2010-09-22 14:16:26 +00001139 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001140 void wait() const {__state_->wait();}
1141 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001142 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001143 future_status
1144 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1145 {return __state_->wait_for(__rel_time);}
1146 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001147 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001148 future_status
1149 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1150 {return __state_->wait_until(__abs_time);}
1151};
1152
Howard Hinnantc834c512011-11-29 18:15:50 +00001153template <class _Rp>
1154future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001155 : __state_(__state)
1156{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001157 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001158}
1159
Howard Hinnantccdd2032010-08-30 18:46:21 +00001160struct __release_shared_count
1161{
1162 void operator()(__shared_count* p) {p->__release_shared();}
1163};
1164
Howard Hinnantc834c512011-11-29 18:15:50 +00001165template <class _Rp>
1166future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001167{
1168 if (__state_)
1169 __state_->__release_shared();
1170}
1171
Howard Hinnantc834c512011-11-29 18:15:50 +00001172template <class _Rp>
1173_Rp
1174future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001175{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001176 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001177 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001178 __state_ = nullptr;
1179 return __s->move();
1180}
1181
Howard Hinnantc834c512011-11-29 18:15:50 +00001182template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001183class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001184{
Howard Hinnantc834c512011-11-29 18:15:50 +00001185 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001186
Howard Hinnantc834c512011-11-29 18:15:50 +00001187 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001188
1189 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001190 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001191
Howard Hinnant74279a52010-09-04 23:28:19 +00001192#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001193 template <class _R1, class _Fp>
1194 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1195 template <class _R1, class _Fp>
1196 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001197#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001198 template <class _R1, class _Fp>
1199 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1200 template <class _R1, class _Fp>
1201 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001202#endif
1203
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001204public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001206 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001207#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001208 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001209 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001210 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1211 future(const future&) = delete;
1212 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001213 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001214 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001215 {
1216 future(std::move(__rhs)).swap(*this);
1217 return *this;
1218 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001219#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001220private:
1221 future(const future&);
1222 future& operator=(const future&);
1223public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001224#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001225 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001226 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001227 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001228
1229 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001230 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001231
Howard Hinnant684902d2010-09-22 14:16:26 +00001232 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001233 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001234
1235 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001237 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001238
Howard Hinnant684902d2010-09-22 14:16:26 +00001239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001240 void wait() const {__state_->wait();}
1241 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001243 future_status
1244 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1245 {return __state_->wait_for(__rel_time);}
1246 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001248 future_status
1249 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1250 {return __state_->wait_until(__abs_time);}
1251};
1252
Howard Hinnantc834c512011-11-29 18:15:50 +00001253template <class _Rp>
1254future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001255 : __state_(__state)
1256{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001257 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001258}
1259
Howard Hinnantc834c512011-11-29 18:15:50 +00001260template <class _Rp>
1261future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001262{
1263 if (__state_)
1264 __state_->__release_shared();
1265}
1266
Howard Hinnantc834c512011-11-29 18:15:50 +00001267template <class _Rp>
1268_Rp&
1269future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001270{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001271 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001272 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001273 __state_ = nullptr;
1274 return __s->copy();
1275}
1276
1277template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001278class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001279{
1280 __assoc_sub_state* __state_;
1281
1282 explicit future(__assoc_sub_state* __state);
1283
1284 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001285 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001286
Howard Hinnant74279a52010-09-04 23:28:19 +00001287#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001288 template <class _R1, class _Fp>
1289 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1290 template <class _R1, class _Fp>
1291 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001292#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001293 template <class _R1, class _Fp>
1294 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1295 template <class _R1, class _Fp>
1296 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001297#endif
1298
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001299public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001301 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001302#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001303 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001304 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001305 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1306 future(const future&) = delete;
1307 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001309 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001310 {
1311 future(std::move(__rhs)).swap(*this);
1312 return *this;
1313 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001314#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001315private:
1316 future(const future&);
1317 future& operator=(const future&);
1318public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001319#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001320 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001321 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001322 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001323
1324 // retrieving the value
1325 void get();
1326
Howard Hinnant684902d2010-09-22 14:16:26 +00001327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001328 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001329
1330 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001331 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001332 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001333
Howard Hinnant684902d2010-09-22 14:16:26 +00001334 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001335 void wait() const {__state_->wait();}
1336 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001337 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001338 future_status
1339 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1340 {return __state_->wait_for(__rel_time);}
1341 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001342 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001343 future_status
1344 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1345 {return __state_->wait_until(__abs_time);}
1346};
1347
Howard Hinnantc834c512011-11-29 18:15:50 +00001348template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001349inline _LIBCPP_INLINE_VISIBILITY
1350void
Howard Hinnant22448042012-07-21 17:46:55 +00001351swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001352{
1353 __x.swap(__y);
1354}
1355
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001356// promise<R>
1357
Howard Hinnant944510a2011-06-14 19:58:17 +00001358template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001359
Howard Hinnantc834c512011-11-29 18:15:50 +00001360template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001361class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001362{
Howard Hinnantc834c512011-11-29 18:15:50 +00001363 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001364
Howard Hinnant684902d2010-09-22 14:16:26 +00001365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001366 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001367
1368 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001369public:
1370 promise();
1371 template <class _Alloc>
1372 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001373#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001374 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001375 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001376 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1377 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001378#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001379private:
1380 promise(const promise& __rhs);
1381public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001382#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001383 ~promise();
1384
1385 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001386#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001387 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001388 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001389 {
1390 promise(std::move(__rhs)).swap(*this);
1391 return *this;
1392 }
1393 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001394#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001395private:
1396 promise& operator=(const promise& __rhs);
1397public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001398#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001400 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001401
1402 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001403 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001404
1405 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001406 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001407#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001408 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001409#endif
1410 void set_exception(exception_ptr __p);
1411
1412 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001413 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001414#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001415 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001416#endif
1417 void set_exception_at_thread_exit(exception_ptr __p);
1418};
1419
Howard Hinnantc834c512011-11-29 18:15:50 +00001420template <class _Rp>
1421promise<_Rp>::promise()
1422 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001423{
1424}
1425
Howard Hinnantc834c512011-11-29 18:15:50 +00001426template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001427template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001428promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001429{
Eric Fiselier0d109272014-10-23 06:24:45 +00001430 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1431 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001432 typedef __allocator_destructor<_A2> _D2;
1433 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001434 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1435 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1436 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001437}
1438
Howard Hinnantc834c512011-11-29 18:15:50 +00001439template <class _Rp>
1440promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001441{
1442 if (__state_)
1443 {
1444 if (!__state_->__has_value() && __state_->use_count() > 1)
1445 __state_->set_exception(make_exception_ptr(
1446 future_error(make_error_code(future_errc::broken_promise))
1447 ));
1448 __state_->__release_shared();
1449 }
1450}
1451
Howard Hinnantc834c512011-11-29 18:15:50 +00001452template <class _Rp>
1453future<_Rp>
1454promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001455{
1456 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001457 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001458 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001459}
1460
Howard Hinnantc834c512011-11-29 18:15:50 +00001461template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001462void
Howard Hinnantc834c512011-11-29 18:15:50 +00001463promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001464{
1465 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001466 __throw_future_error(future_errc::no_state);
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{
1476 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001477 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001478 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001479}
1480
Howard Hinnant74279a52010-09-04 23:28:19 +00001481#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001482
Howard Hinnantc834c512011-11-29 18:15:50 +00001483template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001484void
Howard Hinnantc834c512011-11-29 18:15:50 +00001485promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001486{
Marshall Clow2b36f572016-05-16 16:55:32 +00001487 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001488 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001489 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001490 __state_->set_exception(__p);
1491}
1492
Howard Hinnantc834c512011-11-29 18:15:50 +00001493template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001494void
Howard Hinnantc834c512011-11-29 18:15:50 +00001495promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001496{
1497 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001498 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001499 __state_->set_value_at_thread_exit(__r);
1500}
1501
Howard Hinnant74279a52010-09-04 23:28:19 +00001502#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001503
Howard Hinnantc834c512011-11-29 18:15:50 +00001504template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001505void
Howard Hinnantc834c512011-11-29 18:15:50 +00001506promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001507{
1508 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001509 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001510 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001511}
1512
Howard Hinnant74279a52010-09-04 23:28:19 +00001513#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001514
Howard Hinnantc834c512011-11-29 18:15:50 +00001515template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001516void
Howard Hinnantc834c512011-11-29 18:15:50 +00001517promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001518{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001519 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001520 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001521 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001522 __state_->set_exception_at_thread_exit(__p);
1523}
1524
1525// promise<R&>
1526
Howard Hinnantc834c512011-11-29 18:15:50 +00001527template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001528class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001529{
Howard Hinnantc834c512011-11-29 18:15:50 +00001530 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001531
Howard Hinnant684902d2010-09-22 14:16:26 +00001532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001533 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001534
1535 template <class> friend class packaged_task;
1536
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001537public:
1538 promise();
1539 template <class _Allocator>
1540 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001541#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001543 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001544 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1545 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001546#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001547private:
1548 promise(const promise& __rhs);
1549public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001550#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001551 ~promise();
1552
1553 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001554#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001556 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001557 {
1558 promise(std::move(__rhs)).swap(*this);
1559 return *this;
1560 }
1561 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001562#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001563private:
1564 promise& operator=(const promise& __rhs);
1565public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001566#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001568 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001569
1570 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001571 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001572
1573 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001574 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001575 void set_exception(exception_ptr __p);
1576
1577 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001578 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001579 void set_exception_at_thread_exit(exception_ptr __p);
1580};
1581
Howard Hinnantc834c512011-11-29 18:15:50 +00001582template <class _Rp>
1583promise<_Rp&>::promise()
1584 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001585{
1586}
1587
Howard Hinnantc834c512011-11-29 18:15:50 +00001588template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001589template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001590promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001591{
Eric Fiselier0d109272014-10-23 06:24:45 +00001592 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1593 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001594 typedef __allocator_destructor<_A2> _D2;
1595 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001596 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1597 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1598 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001599}
1600
Howard Hinnantc834c512011-11-29 18:15:50 +00001601template <class _Rp>
1602promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001603{
1604 if (__state_)
1605 {
1606 if (!__state_->__has_value() && __state_->use_count() > 1)
1607 __state_->set_exception(make_exception_ptr(
1608 future_error(make_error_code(future_errc::broken_promise))
1609 ));
1610 __state_->__release_shared();
1611 }
1612}
1613
Howard Hinnantc834c512011-11-29 18:15:50 +00001614template <class _Rp>
1615future<_Rp&>
1616promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001617{
1618 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001619 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001620 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001621}
1622
Howard Hinnantc834c512011-11-29 18:15:50 +00001623template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001624void
Howard Hinnantc834c512011-11-29 18:15:50 +00001625promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001626{
1627 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001628 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001629 __state_->set_value(__r);
1630}
1631
Howard Hinnantc834c512011-11-29 18:15:50 +00001632template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001633void
Howard Hinnantc834c512011-11-29 18:15:50 +00001634promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001635{
Marshall Clow2b36f572016-05-16 16:55:32 +00001636 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001637 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001638 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001639 __state_->set_exception(__p);
1640}
1641
Howard Hinnantc834c512011-11-29 18:15:50 +00001642template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001643void
Howard Hinnantc834c512011-11-29 18:15:50 +00001644promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001645{
1646 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001647 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001648 __state_->set_value_at_thread_exit(__r);
1649}
1650
Howard Hinnantc834c512011-11-29 18:15:50 +00001651template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001652void
Howard Hinnantc834c512011-11-29 18:15:50 +00001653promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001654{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001655 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001656 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001657 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001658 __state_->set_exception_at_thread_exit(__p);
1659}
1660
1661// promise<void>
1662
1663template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001664class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001665{
1666 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001667
Howard Hinnant684902d2010-09-22 14:16:26 +00001668 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001669 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001670
1671 template <class> friend class packaged_task;
1672
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001673public:
1674 promise();
1675 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001676 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001677 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001678#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001680 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001681 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1682 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001683#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001684private:
1685 promise(const promise& __rhs);
1686public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001687#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001688 ~promise();
1689
1690 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001691#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001692 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001693 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001694 {
1695 promise(std::move(__rhs)).swap(*this);
1696 return *this;
1697 }
1698 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001699#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001700private:
1701 promise& operator=(const promise& __rhs);
1702public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001703#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001705 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001706
1707 // retrieving the result
1708 future<void> get_future();
1709
1710 // setting the result
1711 void set_value();
1712 void set_exception(exception_ptr __p);
1713
1714 // setting the result with deferred notification
1715 void set_value_at_thread_exit();
1716 void set_exception_at_thread_exit(exception_ptr __p);
1717};
1718
1719template <class _Alloc>
1720promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1721{
Eric Fiselier0d109272014-10-23 06:24:45 +00001722 typedef __assoc_sub_state_alloc<_Alloc> _State;
1723 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001724 typedef __allocator_destructor<_A2> _D2;
1725 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001726 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1727 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1728 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001729}
1730
Howard Hinnantc834c512011-11-29 18:15:50 +00001731template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001732inline _LIBCPP_INLINE_VISIBILITY
1733void
Howard Hinnant22448042012-07-21 17:46:55 +00001734swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001735{
1736 __x.swap(__y);
1737}
1738
Howard Hinnantc834c512011-11-29 18:15:50 +00001739template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001740 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001741 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001742
Howard Hinnantccdd2032010-08-30 18:46:21 +00001743#ifndef _LIBCPP_HAS_NO_VARIADICS
1744
1745// packaged_task
1746
1747template<class _Fp> class __packaged_task_base;
1748
Howard Hinnantc834c512011-11-29 18:15:50 +00001749template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001750class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001751{
1752 __packaged_task_base(const __packaged_task_base&);
1753 __packaged_task_base& operator=(const __packaged_task_base&);
1754public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001755 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001756 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001757 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001758 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001759 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001760 virtual void destroy() = 0;
1761 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001762 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001763};
1764
1765template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1766
Howard Hinnantc834c512011-11-29 18:15:50 +00001767template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001768class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001769 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001770{
Howard Hinnantc834c512011-11-29 18:15:50 +00001771 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001772public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001773 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001774 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001776 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001778 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001779 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001781 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001782 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001783 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001784 virtual void destroy();
1785 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001786 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001787};
1788
Howard Hinnantc834c512011-11-29 18:15:50 +00001789template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001790void
Howard Hinnantc834c512011-11-29 18:15:50 +00001791__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001792 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001793{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001794 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001795}
1796
Howard Hinnantc834c512011-11-29 18:15:50 +00001797template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001798void
Howard Hinnantc834c512011-11-29 18:15:50 +00001799__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001800{
Howard Hinnantc834c512011-11-29 18:15:50 +00001801 __f_.~__compressed_pair<_Fp, _Alloc>();
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...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001807{
Eric Fiselier0d109272014-10-23 06:24:45 +00001808 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1809 typedef allocator_traits<_Ap> _ATraits;
1810 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001811 _Ap __a(__f_.second());
1812 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001813 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001814}
1815
Howard Hinnantc834c512011-11-29 18:15:50 +00001816template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1817_Rp
1818__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001819{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001820 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001821}
1822
Howard Hinnant944510a2011-06-14 19:58:17 +00001823template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001824
Howard Hinnantc834c512011-11-29 18:15:50 +00001825template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001826class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001827{
Howard Hinnantc834c512011-11-29 18:15:50 +00001828 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001829 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001830 __base* __f_;
1831
1832public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001833 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001834
1835 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001837 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001838 template<class _Fp>
1839 __packaged_task_function(_Fp&& __f);
1840 template<class _Fp, class _Alloc>
1841 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001842
Howard Hinnant22448042012-07-21 17:46:55 +00001843 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1844 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001845
1846 __packaged_task_function(const __packaged_task_function&) = delete;
1847 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1848
1849 ~__packaged_task_function();
1850
Howard Hinnant22448042012-07-21 17:46:55 +00001851 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001852
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001853 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001854 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001855};
1856
Howard Hinnantc834c512011-11-29 18:15:50 +00001857template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001858__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001859{
1860 if (__f.__f_ == nullptr)
1861 __f_ = nullptr;
1862 else if (__f.__f_ == (__base*)&__f.__buf_)
1863 {
1864 __f_ = (__base*)&__buf_;
1865 __f.__f_->__move_to(__f_);
1866 }
1867 else
1868 {
1869 __f_ = __f.__f_;
1870 __f.__f_ = nullptr;
1871 }
1872}
1873
Howard Hinnantc834c512011-11-29 18:15:50 +00001874template<class _Rp, class ..._ArgTypes>
1875template <class _Fp>
1876__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001877 : __f_(nullptr)
1878{
Marshall Clow733d60e2014-04-07 13:32:26 +00001879 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001880 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001881 if (sizeof(_FF) <= sizeof(__buf_))
1882 {
1883 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001884 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001885 }
1886 else
1887 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001888 typedef allocator<_FF> _Ap;
1889 _Ap __a;
1890 typedef __allocator_destructor<_Ap> _Dp;
1891 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1892 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001893 __f_ = __hold.release();
1894 }
1895}
1896
Howard Hinnantc834c512011-11-29 18:15:50 +00001897template<class _Rp, class ..._ArgTypes>
1898template <class _Fp, class _Alloc>
1899__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1900 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001901 : __f_(nullptr)
1902{
Marshall Clow733d60e2014-04-07 13:32:26 +00001903 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001904 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001905 if (sizeof(_FF) <= sizeof(__buf_))
1906 {
1907 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001908 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001909 }
1910 else
1911 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001912 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001913 _Ap __a(__a0);
1914 typedef __allocator_destructor<_Ap> _Dp;
1915 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001916 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1917 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1918 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001919 }
1920}
1921
Howard Hinnantc834c512011-11-29 18:15:50 +00001922template<class _Rp, class ..._ArgTypes>
1923__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001924__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001925{
1926 if (__f_ == (__base*)&__buf_)
1927 __f_->destroy();
1928 else if (__f_)
1929 __f_->destroy_deallocate();
1930 __f_ = nullptr;
1931 if (__f.__f_ == nullptr)
1932 __f_ = nullptr;
1933 else if (__f.__f_ == (__base*)&__f.__buf_)
1934 {
1935 __f_ = (__base*)&__buf_;
1936 __f.__f_->__move_to(__f_);
1937 }
1938 else
1939 {
1940 __f_ = __f.__f_;
1941 __f.__f_ = nullptr;
1942 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001943 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001944}
1945
Howard Hinnantc834c512011-11-29 18:15:50 +00001946template<class _Rp, class ..._ArgTypes>
1947__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001948{
1949 if (__f_ == (__base*)&__buf_)
1950 __f_->destroy();
1951 else if (__f_)
1952 __f_->destroy_deallocate();
1953}
1954
Howard Hinnantc834c512011-11-29 18:15:50 +00001955template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001956void
Howard Hinnant22448042012-07-21 17:46:55 +00001957__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001958{
1959 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1960 {
1961 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1962 __base* __t = (__base*)&__tempbuf;
1963 __f_->__move_to(__t);
1964 __f_->destroy();
1965 __f_ = nullptr;
1966 __f.__f_->__move_to((__base*)&__buf_);
1967 __f.__f_->destroy();
1968 __f.__f_ = nullptr;
1969 __f_ = (__base*)&__buf_;
1970 __t->__move_to((__base*)&__f.__buf_);
1971 __t->destroy();
1972 __f.__f_ = (__base*)&__f.__buf_;
1973 }
1974 else if (__f_ == (__base*)&__buf_)
1975 {
1976 __f_->__move_to((__base*)&__f.__buf_);
1977 __f_->destroy();
1978 __f_ = __f.__f_;
1979 __f.__f_ = (__base*)&__f.__buf_;
1980 }
1981 else if (__f.__f_ == (__base*)&__f.__buf_)
1982 {
1983 __f.__f_->__move_to((__base*)&__buf_);
1984 __f.__f_->destroy();
1985 __f.__f_ = __f_;
1986 __f_ = (__base*)&__buf_;
1987 }
1988 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001989 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001990}
1991
Howard Hinnantc834c512011-11-29 18:15:50 +00001992template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001993inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001994_Rp
1995__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001996{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001997 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001998}
1999
Howard Hinnantc834c512011-11-29 18:15:50 +00002000template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002001class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002002{
2003public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002004 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002005
2006private:
2007 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2008 promise<result_type> __p_;
2009
2010public:
2011 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002012 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002013 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002014 template <class _Fp,
2015 class = typename enable_if
2016 <
2017 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002018 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002019 packaged_task
2020 >::value
2021 >::type
2022 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002023 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002024 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002025 template <class _Fp, class _Allocator,
2026 class = typename enable_if
2027 <
2028 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002029 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002030 packaged_task
2031 >::value
2032 >::type
2033 >
2034 _LIBCPP_INLINE_VISIBILITY
2035 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2036 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2037 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002038 // ~packaged_task() = default;
2039
2040 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002041 packaged_task(const packaged_task&) = delete;
2042 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002043
2044 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002045 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002046 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002047 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002049 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002050 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002051 __f_ = _VSTD::move(__other.__f_);
2052 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002053 return *this;
2054 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002055 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002056 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002057 {
2058 __f_.swap(__other.__f_);
2059 __p_.swap(__other.__p_);
2060 }
2061
Howard Hinnant684902d2010-09-22 14:16:26 +00002062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002063 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002064
2065 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002067 future<result_type> get_future() {return __p_.get_future();}
2068
2069 // execution
2070 void operator()(_ArgTypes... __args);
2071 void make_ready_at_thread_exit(_ArgTypes... __args);
2072
2073 void reset();
2074};
2075
Howard Hinnantc834c512011-11-29 18:15:50 +00002076template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002077void
Howard Hinnantc834c512011-11-29 18:15:50 +00002078packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002079{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002080 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002081 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002082 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002083 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002084#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002085 try
2086 {
2087#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002088 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002089#ifndef _LIBCPP_NO_EXCEPTIONS
2090 }
2091 catch (...)
2092 {
2093 __p_.set_exception(current_exception());
2094 }
2095#endif // _LIBCPP_NO_EXCEPTIONS
2096}
2097
Howard Hinnantc834c512011-11-29 18:15:50 +00002098template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002099void
Howard Hinnantc834c512011-11-29 18:15:50 +00002100packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002101{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002102 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002103 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002104 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002105 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002106#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002107 try
2108 {
2109#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002110 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002111#ifndef _LIBCPP_NO_EXCEPTIONS
2112 }
2113 catch (...)
2114 {
2115 __p_.set_exception_at_thread_exit(current_exception());
2116 }
2117#endif // _LIBCPP_NO_EXCEPTIONS
2118}
2119
Howard Hinnantc834c512011-11-29 18:15:50 +00002120template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002121void
Howard Hinnantc834c512011-11-29 18:15:50 +00002122packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002123{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002124 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002125 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002126 __p_ = promise<result_type>();
2127}
2128
2129template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002130class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002131{
2132public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002133 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002134
2135private:
2136 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2137 promise<result_type> __p_;
2138
2139public:
2140 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002142 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002143 template <class _Fp,
2144 class = typename enable_if
2145 <
2146 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002147 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002148 packaged_task
2149 >::value
2150 >::type
2151 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002152 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002153 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002154 template <class _Fp, class _Allocator,
2155 class = typename enable_if
2156 <
2157 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002158 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002159 packaged_task
2160 >::value
2161 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002162 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002163 _LIBCPP_INLINE_VISIBILITY
2164 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2165 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2166 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002167 // ~packaged_task() = default;
2168
2169 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002170 packaged_task(const packaged_task&) = delete;
2171 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002172
2173 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002174 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002175 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002176 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002177 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002178 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002179 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002180 __f_ = _VSTD::move(__other.__f_);
2181 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002182 return *this;
2183 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002184 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002185 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002186 {
2187 __f_.swap(__other.__f_);
2188 __p_.swap(__other.__p_);
2189 }
2190
Howard Hinnant684902d2010-09-22 14:16:26 +00002191 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002192 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002193
2194 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002195 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002196 future<result_type> get_future() {return __p_.get_future();}
2197
2198 // execution
2199 void operator()(_ArgTypes... __args);
2200 void make_ready_at_thread_exit(_ArgTypes... __args);
2201
2202 void reset();
2203};
2204
2205template<class ..._ArgTypes>
2206void
2207packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2208{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002209 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002210 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002211 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002212 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002213#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002214 try
2215 {
2216#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002217 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002218 __p_.set_value();
2219#ifndef _LIBCPP_NO_EXCEPTIONS
2220 }
2221 catch (...)
2222 {
2223 __p_.set_exception(current_exception());
2224 }
2225#endif // _LIBCPP_NO_EXCEPTIONS
2226}
2227
2228template<class ..._ArgTypes>
2229void
2230packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2231{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002232 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002233 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002234 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002235 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002236#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002237 try
2238 {
2239#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002240 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002241 __p_.set_value_at_thread_exit();
2242#ifndef _LIBCPP_NO_EXCEPTIONS
2243 }
2244 catch (...)
2245 {
2246 __p_.set_exception_at_thread_exit(current_exception());
2247 }
2248#endif // _LIBCPP_NO_EXCEPTIONS
2249}
2250
2251template<class ..._ArgTypes>
2252void
2253packaged_task<void(_ArgTypes...)>::reset()
2254{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002255 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002256 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002257 __p_ = promise<result_type>();
2258}
2259
2260template <class _Callable>
2261inline _LIBCPP_INLINE_VISIBILITY
2262void
Howard Hinnant22448042012-07-21 17:46:55 +00002263swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002264{
2265 __x.swap(__y);
2266}
2267
Marshall Clowa0a057e2017-11-27 20:47:54 +00002268template <class _Callable, class _Alloc>
2269struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2270 : public true_type {};
2271
Howard Hinnantc834c512011-11-29 18:15:50 +00002272template <class _Rp, class _Fp>
2273future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002274#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002275__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002276#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002277__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002278#endif
2279{
Howard Hinnantc834c512011-11-29 18:15:50 +00002280 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2281 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2282 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002283}
2284
Howard Hinnantc834c512011-11-29 18:15:50 +00002285template <class _Rp, class _Fp>
2286future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002287#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002288__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002289#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002290__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002291#endif
2292{
Howard Hinnantc834c512011-11-29 18:15:50 +00002293 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2294 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2295 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2296 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002297}
2298
Howard Hinnantc834c512011-11-29 18:15:50 +00002299template <class _Fp, class... _Args>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002300class __async_func
2301{
Howard Hinnantc834c512011-11-29 18:15:50 +00002302 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002303
2304public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002305 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002306
2307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002308 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002309 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002310
2311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002312 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002313
Howard Hinnantc834c512011-11-29 18:15:50 +00002314 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002315 {
2316 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2317 return __execute(_Index());
2318 }
2319private:
2320 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002321 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002322 __execute(__tuple_indices<_Indices...>)
2323 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002324 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002325 }
2326};
2327
Marshall Clowd56a5b62013-11-03 22:06:53 +00002328inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002329{ return (int(__policy) & int(__value)) != 0; }
2330
Howard Hinnantc834c512011-11-29 18:15:50 +00002331template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002332_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002333future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2334async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002335{
Howard Hinnantc834c512011-11-29 18:15:50 +00002336 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2337 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002338
2339#ifndef _LIBCPP_NO_EXCEPTIONS
2340 try
2341 {
2342#endif
2343 if (__does_policy_contain(__policy, launch::async))
2344 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002345 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002346#ifndef _LIBCPP_NO_EXCEPTIONS
2347 }
2348 catch ( ... ) { if (__policy == launch::async) throw ; }
2349#endif
2350
2351 if (__does_policy_contain(__policy, launch::deferred))
2352 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002353 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002354 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002355}
2356
Howard Hinnantc834c512011-11-29 18:15:50 +00002357template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002358_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002359future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2360async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002361{
Howard Hinnantc834c512011-11-29 18:15:50 +00002362 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002363 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002364}
2365
2366#endif // _LIBCPP_HAS_NO_VARIADICS
2367
Howard Hinnante6a10852010-09-03 21:46:37 +00002368// shared_future
2369
Howard Hinnantc834c512011-11-29 18:15:50 +00002370template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002371class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002372{
Howard Hinnantc834c512011-11-29 18:15:50 +00002373 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002374
2375public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002376 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002377 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002378 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002379 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002380 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002381#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002383 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002384 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002386 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002387 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002388#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002389 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002390 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant74279a52010-09-04 23:28:19 +00002391#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002392 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002393 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002394 {
2395 shared_future(std::move(__rhs)).swap(*this);
2396 return *this;
2397 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002398#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002399
2400 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002402 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002403
Howard Hinnant684902d2010-09-22 14:16:26 +00002404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002405 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002406
2407 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002408 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002409 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002410
Howard Hinnant684902d2010-09-22 14:16:26 +00002411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002412 void wait() const {__state_->wait();}
2413 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002414 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002415 future_status
2416 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2417 {return __state_->wait_for(__rel_time);}
2418 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002419 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002420 future_status
2421 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2422 {return __state_->wait_until(__abs_time);}
2423};
2424
Howard Hinnantc834c512011-11-29 18:15:50 +00002425template <class _Rp>
2426shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002427{
2428 if (__state_)
2429 __state_->__release_shared();
2430}
2431
Howard Hinnantc834c512011-11-29 18:15:50 +00002432template <class _Rp>
2433shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002434shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002435{
2436 if (__rhs.__state_)
2437 __rhs.__state_->__add_shared();
2438 if (__state_)
2439 __state_->__release_shared();
2440 __state_ = __rhs.__state_;
2441 return *this;
2442}
2443
Howard Hinnantc834c512011-11-29 18:15:50 +00002444template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002445class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002446{
Howard Hinnantc834c512011-11-29 18:15:50 +00002447 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002448
2449public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002451 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002453 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2454 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002455#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002456 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002457 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002458 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002459 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002460 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002461 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002462#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002463 ~shared_future();
2464 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002465#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002467 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002468 {
2469 shared_future(std::move(__rhs)).swap(*this);
2470 return *this;
2471 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002472#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002473
2474 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002475 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002476 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002477
Howard Hinnant684902d2010-09-22 14:16:26 +00002478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002479 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002480
2481 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002482 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002483 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002484
Howard Hinnant684902d2010-09-22 14:16:26 +00002485 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002486 void wait() const {__state_->wait();}
2487 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002488 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002489 future_status
2490 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2491 {return __state_->wait_for(__rel_time);}
2492 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002493 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002494 future_status
2495 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2496 {return __state_->wait_until(__abs_time);}
2497};
2498
Howard Hinnantc834c512011-11-29 18:15:50 +00002499template <class _Rp>
2500shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002501{
2502 if (__state_)
2503 __state_->__release_shared();
2504}
2505
Howard Hinnantc834c512011-11-29 18:15:50 +00002506template <class _Rp>
2507shared_future<_Rp&>&
2508shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002509{
2510 if (__rhs.__state_)
2511 __rhs.__state_->__add_shared();
2512 if (__state_)
2513 __state_->__release_shared();
2514 __state_ = __rhs.__state_;
2515 return *this;
2516}
2517
2518template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002519class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002520{
2521 __assoc_sub_state* __state_;
2522
2523public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002525 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002527 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2528 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002529#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002531 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002532 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002534 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002535 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002536#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002537 ~shared_future();
2538 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002539#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002541 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002542 {
2543 shared_future(std::move(__rhs)).swap(*this);
2544 return *this;
2545 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002546#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002547
2548 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002550 void get() const {__state_->copy();}
2551
Howard Hinnant684902d2010-09-22 14:16:26 +00002552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002553 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002554
2555 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002557 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002558
Howard Hinnant684902d2010-09-22 14:16:26 +00002559 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002560 void wait() const {__state_->wait();}
2561 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002562 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002563 future_status
2564 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2565 {return __state_->wait_for(__rel_time);}
2566 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002568 future_status
2569 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2570 {return __state_->wait_until(__abs_time);}
2571};
2572
Howard Hinnantc834c512011-11-29 18:15:50 +00002573template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002574inline _LIBCPP_INLINE_VISIBILITY
2575void
Howard Hinnant22448042012-07-21 17:46:55 +00002576swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002577{
2578 __x.swap(__y);
2579}
2580
Howard Hinnantc834c512011-11-29 18:15:50 +00002581template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002582inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002583shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002584future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002585{
Howard Hinnantc834c512011-11-29 18:15:50 +00002586 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002587}
2588
Howard Hinnantc834c512011-11-29 18:15:50 +00002589template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002590inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002591shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002592future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002593{
Howard Hinnantc834c512011-11-29 18:15:50 +00002594 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002595}
2596
Howard Hinnante65e8e32010-12-02 16:45:21 +00002597#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2598
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002599inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002600shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002601future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002602{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002603 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002604}
2605
Howard Hinnante65e8e32010-12-02 16:45:21 +00002606#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2607
Howard Hinnantc51e1022010-05-11 19:42:16 +00002608_LIBCPP_END_NAMESPACE_STD
2609
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002610#endif // !_LIBCPP_HAS_NO_THREADS
2611
Howard Hinnantc51e1022010-05-11 19:42:16 +00002612#endif // _LIBCPP_FUTURE