blob: deb7725f73de1d2d6b029d09eb3092f2b75d1de9 [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
Howard Hinnantda760a82013-06-29 18:38:17 +0000411typedef underlying_type<launch>::type __launch_underlying_type;
Howard Hinnantda760a82013-06-29 18:38:17 +0000412
413inline _LIBCPP_INLINE_VISIBILITY
414_LIBCPP_CONSTEXPR
415launch
416operator&(launch __x, launch __y)
417{
418 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
419 static_cast<__launch_underlying_type>(__y));
420}
421
422inline _LIBCPP_INLINE_VISIBILITY
423_LIBCPP_CONSTEXPR
424launch
425operator|(launch __x, launch __y)
426{
427 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
428 static_cast<__launch_underlying_type>(__y));
429}
430
431inline _LIBCPP_INLINE_VISIBILITY
432_LIBCPP_CONSTEXPR
433launch
434operator^(launch __x, launch __y)
435{
436 return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
437 static_cast<__launch_underlying_type>(__y));
438}
439
440inline _LIBCPP_INLINE_VISIBILITY
441_LIBCPP_CONSTEXPR
442launch
443operator~(launch __x)
444{
Howard Hinnant373d7602013-07-02 18:01:41 +0000445 return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
Howard Hinnantda760a82013-06-29 18:38:17 +0000446}
447
448inline _LIBCPP_INLINE_VISIBILITY
449launch&
450operator&=(launch& __x, launch __y)
451{
452 __x = __x & __y; return __x;
453}
454
455inline _LIBCPP_INLINE_VISIBILITY
456launch&
457operator|=(launch& __x, launch __y)
458{
459 __x = __x | __y; return __x;
460}
461
462inline _LIBCPP_INLINE_VISIBILITY
463launch&
464operator^=(launch& __x, launch __y)
465{
466 __x = __x ^ __y; return __x;
467}
468
469#endif // !_LIBCPP_HAS_NO_STRONG_ENUMS
470
Howard Hinnantc51e1022010-05-11 19:42:16 +0000471//enum class future_status
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000472_LIBCPP_DECLARE_STRONG_ENUM(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000473{
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474 ready,
475 timeout,
476 deferred
477};
Howard Hinnant09bc0c92011-12-02 19:36:40 +0000478_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000479
Howard Hinnant8331b762013-03-06 23:30:19 +0000480_LIBCPP_FUNC_VIS
Howard Hinnant22448042012-07-21 17:46:55 +0000481const error_category& future_category() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000482
483inline _LIBCPP_INLINE_VISIBILITY
484error_code
Howard Hinnant22448042012-07-21 17:46:55 +0000485make_error_code(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000486{
487 return error_code(static_cast<int>(__e), future_category());
488}
489
490inline _LIBCPP_INLINE_VISIBILITY
491error_condition
Howard Hinnant22448042012-07-21 17:46:55 +0000492make_error_condition(future_errc __e) _NOEXCEPT
Howard Hinnant96803d92010-08-25 17:32:05 +0000493{
494 return error_condition(static_cast<int>(__e), future_category());
495}
496
Mehdi Amini228053d2017-05-04 17:08:54 +0000497class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
Howard Hinnant96803d92010-08-25 17:32:05 +0000498 : public logic_error
499{
500 error_code __ec_;
501public:
502 future_error(error_code __ec);
Marshall Clowd4a669c2016-11-14 18:56:24 +0000503#if _LIBCPP_STD_VERS > 14
504 explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {}
505#endif
Howard Hinnant684902d2010-09-22 14:16:26 +0000506 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +0000507 const error_code& code() const _NOEXCEPT {return __ec_;}
Howard Hinnant0dcdf022011-07-07 21:03:52 +0000508
509 virtual ~future_error() _NOEXCEPT;
Howard Hinnant96803d92010-08-25 17:32:05 +0000510};
511
Louis Dionne16fe2952018-07-11 23:14:33 +0000512_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
Mehdi Amini228053d2017-05-04 17:08:54 +0000513#ifndef _LIBCPP_NO_EXCEPTIONS
514_LIBCPP_AVAILABILITY_FUTURE_ERROR
515#endif
Eric Fiselier43641592015-10-02 21:25:15 +0000516void __throw_future_error(future_errc _Ev)
Marshall Clow7b3742d2015-09-03 15:11:32 +0000517{
518#ifndef _LIBCPP_NO_EXCEPTIONS
519 throw future_error(make_error_code(_Ev));
520#else
Eric Fiselierb2c89f22016-12-24 01:56:25 +0000521 ((void)_Ev);
Marshall Clow8fea1612016-08-25 15:09:01 +0000522 _VSTD::abort();
Marshall Clow7b3742d2015-09-03 15:11:32 +0000523#endif
524}
525
Mehdi Amini228053d2017-05-04 17:08:54 +0000526class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000527 : public __shared_count
528{
529protected:
530 exception_ptr __exception_;
531 mutable mutex __mut_;
532 mutable condition_variable __cv_;
533 unsigned __state_;
534
Howard Hinnant719bda32011-05-28 14:41:13 +0000535 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000536 void __sub_wait(unique_lock<mutex>& __lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000537public:
538 enum
539 {
540 __constructed = 1,
541 __future_attached = 2,
542 ready = 4,
543 deferred = 8
544 };
545
Howard Hinnant684902d2010-09-22 14:16:26 +0000546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000547 __assoc_sub_state() : __state_(0) {}
548
Howard Hinnant684902d2010-09-22 14:16:26 +0000549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000550 bool __has_value() const
551 {return (__state_ & __constructed) || (__exception_ != nullptr);}
552
Howard Hinnant684902d2010-09-22 14:16:26 +0000553 _LIBCPP_INLINE_VISIBILITY
Louis Dionne2c0d2262018-08-24 14:00:59 +0000554 void __attach_future() {
Howard Hinnante667ecc2013-01-14 20:01:24 +0000555 lock_guard<mutex> __lk(__mut_);
Louis Dionne2c0d2262018-08-24 14:00:59 +0000556 bool __has_future_attached = (__state_ & __future_attached) != 0;
557 if (__has_future_attached)
558 __throw_future_error(future_errc::future_already_retrieved);
559 this->__add_shared();
Howard Hinnante667ecc2013-01-14 20:01:24 +0000560 __state_ |= __future_attached;
561 }
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000562
Howard Hinnant684902d2010-09-22 14:16:26 +0000563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +0000564 void __set_deferred() {__state_ |= deferred;}
565
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000566 void __make_ready();
Howard Hinnant684902d2010-09-22 14:16:26 +0000567 _LIBCPP_INLINE_VISIBILITY
Marshall Clowdfcbb432013-10-13 01:02:45 +0000568 bool __is_ready() const {return (__state_ & ready) != 0;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000569
570 void set_value();
571 void set_value_at_thread_exit();
572
573 void set_exception(exception_ptr __p);
574 void set_exception_at_thread_exit(exception_ptr __p);
575
576 void copy();
577
Howard Hinnantccdd2032010-08-30 18:46:21 +0000578 void wait();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000579 template <class _Rep, class _Period>
580 future_status
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000581 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000582 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
583 template <class _Clock, class _Duration>
Shoaib Meenai55f3a462017-03-02 03:22:18 +0000584 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000585 future_status
586 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000587
588 virtual void __execute();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000589};
590
Howard Hinnantf4712b92010-08-28 21:01:06 +0000591template <class _Clock, class _Duration>
592future_status
593__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
594{
595 unique_lock<mutex> __lk(__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000596 if (__state_ & deferred)
597 return future_status::deferred;
598 while (!(__state_ & ready) && _Clock::now() < __abs_time)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000599 __cv_.wait_until(__lk, __abs_time);
600 if (__state_ & ready)
601 return future_status::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000602 return future_status::timeout;
603}
604
605template <class _Rep, class _Period>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000606inline
Howard Hinnantf4712b92010-08-28 21:01:06 +0000607future_status
608__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
609{
Howard Hinnantc8dbd222010-11-20 19:16:30 +0000610 return wait_until(chrono::steady_clock::now() + __rel_time);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000611}
612
Howard Hinnantc834c512011-11-29 18:15:50 +0000613template <class _Rp>
Louis Dionne3b967d02019-12-10 18:00:42 -0500614class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000615 : public __assoc_sub_state
616{
617 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000618 typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000619protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000620 _Up __value_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000621
Howard Hinnant719bda32011-05-28 14:41:13 +0000622 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000623public:
624
625 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000626#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000627 void set_value(_Arg&& __arg);
628#else
629 void set_value(_Arg& __arg);
630#endif
631
632 template <class _Arg>
Howard Hinnant74279a52010-09-04 23:28:19 +0000633#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000634 void set_value_at_thread_exit(_Arg&& __arg);
635#else
636 void set_value_at_thread_exit(_Arg& __arg);
637#endif
638
Howard Hinnantc834c512011-11-29 18:15:50 +0000639 _Rp move();
640 typename add_lvalue_reference<_Rp>::type copy();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000641};
642
Howard Hinnantc834c512011-11-29 18:15:50 +0000643template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000644void
Howard Hinnantc834c512011-11-29 18:15:50 +0000645__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000646{
647 if (this->__state_ & base::__constructed)
Howard Hinnantc834c512011-11-29 18:15:50 +0000648 reinterpret_cast<_Rp*>(&__value_)->~_Rp();
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000649 delete this;
650}
651
Howard Hinnantc834c512011-11-29 18:15:50 +0000652template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000653template <class _Arg>
Mehdi Amini228053d2017-05-04 17:08:54 +0000654_LIBCPP_AVAILABILITY_FUTURE
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000655void
Howard Hinnant74279a52010-09-04 23:28:19 +0000656#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000657__assoc_state<_Rp>::set_value(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000658#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000659__assoc_state<_Rp>::set_value(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000660#endif
661{
662 unique_lock<mutex> __lk(this->__mut_);
663 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000664 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000665 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000666 this->__state_ |= base::__constructed | base::ready;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000667 __cv_.notify_all();
668}
669
Howard Hinnantc834c512011-11-29 18:15:50 +0000670template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000671template <class _Arg>
672void
Howard Hinnant74279a52010-09-04 23:28:19 +0000673#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +0000674__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000675#else
Howard Hinnantc834c512011-11-29 18:15:50 +0000676__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000677#endif
678{
679 unique_lock<mutex> __lk(this->__mut_);
680 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000681 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnantc834c512011-11-29 18:15:50 +0000682 ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000683 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000684 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000685}
686
Howard Hinnantc834c512011-11-29 18:15:50 +0000687template <class _Rp>
688_Rp
689__assoc_state<_Rp>::move()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000690{
691 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000692 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000693 if (this->__exception_ != nullptr)
694 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000695 return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000696}
697
Howard Hinnantc834c512011-11-29 18:15:50 +0000698template <class _Rp>
699typename add_lvalue_reference<_Rp>::type
700__assoc_state<_Rp>::copy()
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000701{
702 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000703 this->__sub_wait(__lk);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000704 if (this->__exception_ != nullptr)
705 rethrow_exception(this->__exception_);
Howard Hinnantc834c512011-11-29 18:15:50 +0000706 return *reinterpret_cast<_Rp*>(&__value_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000707}
708
Howard Hinnantc834c512011-11-29 18:15:50 +0000709template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000710class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000711 : public __assoc_sub_state
712{
713 typedef __assoc_sub_state base;
Howard Hinnantc834c512011-11-29 18:15:50 +0000714 typedef _Rp* _Up;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000715protected:
Howard Hinnantc834c512011-11-29 18:15:50 +0000716 _Up __value_;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000717
Howard Hinnant719bda32011-05-28 14:41:13 +0000718 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000719public:
720
Howard Hinnantc834c512011-11-29 18:15:50 +0000721 void set_value(_Rp& __arg);
722 void set_value_at_thread_exit(_Rp& __arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000723
Howard Hinnantc834c512011-11-29 18:15:50 +0000724 _Rp& copy();
Howard Hinnantf4712b92010-08-28 21:01:06 +0000725};
726
Howard Hinnantc834c512011-11-29 18:15:50 +0000727template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000728void
Howard Hinnantc834c512011-11-29 18:15:50 +0000729__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000730{
731 delete this;
732}
733
Howard Hinnantc834c512011-11-29 18:15:50 +0000734template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000735void
Howard Hinnantc834c512011-11-29 18:15:50 +0000736__assoc_state<_Rp&>::set_value(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000737{
738 unique_lock<mutex> __lk(this->__mut_);
739 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000740 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000741 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000742 this->__state_ |= base::__constructed | base::ready;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000743 __cv_.notify_all();
744}
745
Howard Hinnantc834c512011-11-29 18:15:50 +0000746template <class _Rp>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000747void
Howard Hinnantc834c512011-11-29 18:15:50 +0000748__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
Howard Hinnantf4712b92010-08-28 21:01:06 +0000749{
750 unique_lock<mutex> __lk(this->__mut_);
751 if (this->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +0000752 __throw_future_error(future_errc::promise_already_satisfied);
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000753 __value_ = _VSTD::addressof(__arg);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000754 this->__state_ |= base::__constructed;
Howard Hinnant15d55052010-10-14 19:18:04 +0000755 __thread_local_data()->__make_ready_at_thread_exit(this);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000756}
757
Howard Hinnantc834c512011-11-29 18:15:50 +0000758template <class _Rp>
759_Rp&
760__assoc_state<_Rp&>::copy()
Howard Hinnantf4712b92010-08-28 21:01:06 +0000761{
762 unique_lock<mutex> __lk(this->__mut_);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000763 this->__sub_wait(__lk);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000764 if (this->__exception_ != nullptr)
765 rethrow_exception(this->__exception_);
766 return *__value_;
767}
768
Howard Hinnantc834c512011-11-29 18:15:50 +0000769template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000770class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
Howard Hinnantc834c512011-11-29 18:15:50 +0000771 : public __assoc_state<_Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000772{
Howard Hinnantc834c512011-11-29 18:15:50 +0000773 typedef __assoc_state<_Rp> base;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000774 _Alloc __alloc_;
775
Howard Hinnant719bda32011-05-28 14:41:13 +0000776 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000777public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000779 explicit __assoc_state_alloc(const _Alloc& __a)
780 : __alloc_(__a) {}
781};
782
Howard Hinnantc834c512011-11-29 18:15:50 +0000783template <class _Rp, class _Alloc>
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000784void
Howard Hinnantc834c512011-11-29 18:15:50 +0000785__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000786{
787 if (this->__state_ & base::__constructed)
Howard Hinnant8bea6da2013-08-08 18:38:55 +0000788 reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
Eric Fiselierf8898c82015-02-05 23:01:40 +0000789 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
790 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000791 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000792 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000793 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000794 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000795}
796
Howard Hinnantc834c512011-11-29 18:15:50 +0000797template <class _Rp, class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000798class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +0000799 : public __assoc_state<_Rp&>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000800{
Howard Hinnantc834c512011-11-29 18:15:50 +0000801 typedef __assoc_state<_Rp&> base;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000802 _Alloc __alloc_;
803
Howard Hinnant719bda32011-05-28 14:41:13 +0000804 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnantf4712b92010-08-28 21:01:06 +0000805public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000806 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf4712b92010-08-28 21:01:06 +0000807 explicit __assoc_state_alloc(const _Alloc& __a)
808 : __alloc_(__a) {}
809};
810
Howard Hinnantc834c512011-11-29 18:15:50 +0000811template <class _Rp, class _Alloc>
Howard Hinnantf4712b92010-08-28 21:01:06 +0000812void
Howard Hinnantc834c512011-11-29 18:15:50 +0000813__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnantf4712b92010-08-28 21:01:06 +0000814{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000815 typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _Al;
816 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000817 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000818 _Al __a(__alloc_);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000819 this->~__assoc_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000820 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantf4712b92010-08-28 21:01:06 +0000821}
822
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000823template <class _Alloc>
Mehdi Amini228053d2017-05-04 17:08:54 +0000824class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000825 : public __assoc_sub_state
826{
827 typedef __assoc_sub_state base;
828 _Alloc __alloc_;
829
Howard Hinnant719bda32011-05-28 14:41:13 +0000830 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000831public:
Howard Hinnant684902d2010-09-22 14:16:26 +0000832 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000833 explicit __assoc_sub_state_alloc(const _Alloc& __a)
834 : __alloc_(__a) {}
835};
836
837template <class _Alloc>
838void
Howard Hinnant719bda32011-05-28 14:41:13 +0000839__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000840{
Eric Fiselierf8898c82015-02-05 23:01:40 +0000841 typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _Al;
842 typedef allocator_traits<_Al> _ATraits;
Eric Fiselier0d109272014-10-23 06:24:45 +0000843 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Eric Fiselierf8898c82015-02-05 23:01:40 +0000844 _Al __a(__alloc_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000845 this->~__assoc_sub_state_alloc();
Eric Fiselier0d109272014-10-23 06:24:45 +0000846 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnant3820f6b2010-08-27 20:10:19 +0000847}
848
Howard Hinnantc834c512011-11-29 18:15:50 +0000849template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000850class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000851 : public __assoc_state<_Rp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000852{
Howard Hinnantc834c512011-11-29 18:15:50 +0000853 typedef __assoc_state<_Rp> base;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000854
Howard Hinnantc834c512011-11-29 18:15:50 +0000855 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000856
857public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000858#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000859 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000860 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000861#endif
862
863 virtual void __execute();
864};
865
Howard Hinnant74279a52010-09-04 23:28:19 +0000866#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000867
Howard Hinnantc834c512011-11-29 18:15:50 +0000868template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000869inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000870__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
871 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000872{
873 this->__set_deferred();
874}
875
Howard Hinnant74279a52010-09-04 23:28:19 +0000876#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000877
Howard Hinnantc834c512011-11-29 18:15:50 +0000878template <class _Rp, class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000879void
Howard Hinnantc834c512011-11-29 18:15:50 +0000880__deferred_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000881{
882#ifndef _LIBCPP_NO_EXCEPTIONS
883 try
884 {
885#endif // _LIBCPP_NO_EXCEPTIONS
886 this->set_value(__func_());
887#ifndef _LIBCPP_NO_EXCEPTIONS
888 }
889 catch (...)
890 {
891 this->set_exception(current_exception());
892 }
893#endif // _LIBCPP_NO_EXCEPTIONS
894}
895
Howard Hinnantc834c512011-11-29 18:15:50 +0000896template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000897class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000898 : public __assoc_sub_state
899{
900 typedef __assoc_sub_state base;
901
Howard Hinnantc834c512011-11-29 18:15:50 +0000902 _Fp __func_;
Howard Hinnantccdd2032010-08-30 18:46:21 +0000903
904public:
Howard Hinnant74279a52010-09-04 23:28:19 +0000905#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000906 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000907 explicit __deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +0000908#endif
909
910 virtual void __execute();
911};
912
Howard Hinnant74279a52010-09-04 23:28:19 +0000913#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000914
Howard Hinnantc834c512011-11-29 18:15:50 +0000915template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000916inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000917__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
918 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnantccdd2032010-08-30 18:46:21 +0000919{
920 this->__set_deferred();
921}
922
Howard Hinnant74279a52010-09-04 23:28:19 +0000923#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantccdd2032010-08-30 18:46:21 +0000924
Howard Hinnantc834c512011-11-29 18:15:50 +0000925template <class _Fp>
Howard Hinnantccdd2032010-08-30 18:46:21 +0000926void
Howard Hinnantc834c512011-11-29 18:15:50 +0000927__deferred_assoc_state<void, _Fp>::__execute()
Howard Hinnantccdd2032010-08-30 18:46:21 +0000928{
929#ifndef _LIBCPP_NO_EXCEPTIONS
930 try
931 {
932#endif // _LIBCPP_NO_EXCEPTIONS
933 __func_();
934 this->set_value();
935#ifndef _LIBCPP_NO_EXCEPTIONS
936 }
937 catch (...)
938 {
939 this->set_exception(current_exception());
940 }
941#endif // _LIBCPP_NO_EXCEPTIONS
942}
943
Howard Hinnantc834c512011-11-29 18:15:50 +0000944template <class _Rp, class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +0000945class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
Howard Hinnantc834c512011-11-29 18:15:50 +0000946 : public __assoc_state<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000947{
Howard Hinnantc834c512011-11-29 18:15:50 +0000948 typedef __assoc_state<_Rp> base;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000949
Howard Hinnantc834c512011-11-29 18:15:50 +0000950 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000951
Howard Hinnant719bda32011-05-28 14:41:13 +0000952 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +0000953public:
954#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000955 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +0000956 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +0000957#endif
958
959 virtual void __execute();
960};
961
962#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
963
Howard Hinnantc834c512011-11-29 18:15:50 +0000964template <class _Rp, class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +0000965inline
Howard Hinnantc834c512011-11-29 18:15:50 +0000966__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
967 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +0000968{
969}
970
971#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
972
Howard Hinnantc834c512011-11-29 18:15:50 +0000973template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000974void
Howard Hinnantc834c512011-11-29 18:15:50 +0000975__async_assoc_state<_Rp, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +0000976{
977#ifndef _LIBCPP_NO_EXCEPTIONS
978 try
979 {
980#endif // _LIBCPP_NO_EXCEPTIONS
981 this->set_value(__func_());
982#ifndef _LIBCPP_NO_EXCEPTIONS
983 }
984 catch (...)
985 {
986 this->set_exception(current_exception());
987 }
988#endif // _LIBCPP_NO_EXCEPTIONS
989}
990
Howard Hinnantc834c512011-11-29 18:15:50 +0000991template <class _Rp, class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +0000992void
Howard Hinnantc834c512011-11-29 18:15:50 +0000993__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +0000994{
995 this->wait();
996 base::__on_zero_shared();
997}
998
Howard Hinnantc834c512011-11-29 18:15:50 +0000999template <class _Fp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001000class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001001 : public __assoc_sub_state
1002{
1003 typedef __assoc_sub_state base;
1004
Howard Hinnantc834c512011-11-29 18:15:50 +00001005 _Fp __func_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001006
Howard Hinnant719bda32011-05-28 14:41:13 +00001007 virtual void __on_zero_shared() _NOEXCEPT;
Howard Hinnant95cfd872011-05-19 15:05:04 +00001008public:
1009#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001010 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001011 explicit __async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001012#endif
1013
1014 virtual void __execute();
1015};
1016
1017#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018
Howard Hinnantc834c512011-11-29 18:15:50 +00001019template <class _Fp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001020inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001021__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
1022 : __func_(_VSTD::forward<_Fp>(__f))
Howard Hinnant95cfd872011-05-19 15:05:04 +00001023{
1024}
1025
1026#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1027
Howard Hinnantc834c512011-11-29 18:15:50 +00001028template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001029void
Howard Hinnantc834c512011-11-29 18:15:50 +00001030__async_assoc_state<void, _Fp>::__execute()
Howard Hinnant95cfd872011-05-19 15:05:04 +00001031{
1032#ifndef _LIBCPP_NO_EXCEPTIONS
1033 try
1034 {
1035#endif // _LIBCPP_NO_EXCEPTIONS
1036 __func_();
1037 this->set_value();
1038#ifndef _LIBCPP_NO_EXCEPTIONS
1039 }
1040 catch (...)
1041 {
1042 this->set_exception(current_exception());
1043 }
1044#endif // _LIBCPP_NO_EXCEPTIONS
1045}
1046
Howard Hinnantc834c512011-11-29 18:15:50 +00001047template <class _Fp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001048void
Howard Hinnantc834c512011-11-29 18:15:50 +00001049__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
Howard Hinnant95cfd872011-05-19 15:05:04 +00001050{
1051 this->wait();
1052 base::__on_zero_shared();
1053}
1054
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001055template <class _Rp> class _LIBCPP_TEMPLATE_VIS promise;
1056template <class _Rp> class _LIBCPP_TEMPLATE_VIS shared_future;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001057
1058// future
1059
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001060template <class _Rp> class _LIBCPP_TEMPLATE_VIS future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001061
Howard Hinnantc834c512011-11-29 18:15:50 +00001062template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001063_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00001064#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001065__make_deferred_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001066#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001067__make_deferred_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001068#endif
1069
Howard Hinnantc834c512011-11-29 18:15:50 +00001070template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05001071_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00001072#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001073__make_async_assoc_state(_Fp&& __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001074#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001075__make_async_assoc_state(_Fp __f);
Howard Hinnant95cfd872011-05-19 15:05:04 +00001076#endif
1077
Howard Hinnantc834c512011-11-29 18:15:50 +00001078template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001079class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001080{
Howard Hinnantc834c512011-11-29 18:15:50 +00001081 __assoc_state<_Rp>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001082
Howard Hinnantc834c512011-11-29 18:15:50 +00001083 explicit future(__assoc_state<_Rp>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001084
1085 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001086 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001087
Howard Hinnant74279a52010-09-04 23:28:19 +00001088#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001089 template <class _R1, class _Fp>
1090 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1091 template <class _R1, class _Fp>
1092 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001093#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001094 template <class _R1, class _Fp>
1095 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1096 template <class _R1, class _Fp>
1097 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001098#endif
1099
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001100public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001101 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001102 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001103#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001104 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001105 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001106 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1107 future(const future&) = delete;
1108 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001109 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001110 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001111 {
1112 future(std::move(__rhs)).swap(*this);
1113 return *this;
1114 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001115#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001116private:
1117 future(const future&);
1118 future& operator=(const future&);
1119public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001120#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001121 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001122 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001123 shared_future<_Rp> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001124
1125 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001126 _Rp get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001127
Howard Hinnant684902d2010-09-22 14:16:26 +00001128 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001129 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001130
1131 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001133 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001134
Howard Hinnant684902d2010-09-22 14:16:26 +00001135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001136 void wait() const {__state_->wait();}
1137 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001138 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001139 future_status
1140 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1141 {return __state_->wait_for(__rel_time);}
1142 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001143 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001144 future_status
1145 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1146 {return __state_->wait_until(__abs_time);}
1147};
1148
Howard Hinnantc834c512011-11-29 18:15:50 +00001149template <class _Rp>
1150future<_Rp>::future(__assoc_state<_Rp>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001151 : __state_(__state)
1152{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001153 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001154}
1155
Howard Hinnantccdd2032010-08-30 18:46:21 +00001156struct __release_shared_count
1157{
1158 void operator()(__shared_count* p) {p->__release_shared();}
1159};
1160
Howard Hinnantc834c512011-11-29 18:15:50 +00001161template <class _Rp>
1162future<_Rp>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001163{
1164 if (__state_)
1165 __state_->__release_shared();
1166}
1167
Howard Hinnantc834c512011-11-29 18:15:50 +00001168template <class _Rp>
1169_Rp
1170future<_Rp>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001171{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001172 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001173 __assoc_state<_Rp>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001174 __state_ = nullptr;
1175 return __s->move();
1176}
1177
Howard Hinnantc834c512011-11-29 18:15:50 +00001178template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001179class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001180{
Howard Hinnantc834c512011-11-29 18:15:50 +00001181 __assoc_state<_Rp&>* __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001182
Howard Hinnantc834c512011-11-29 18:15:50 +00001183 explicit future(__assoc_state<_Rp&>* __state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001184
1185 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001186 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001187
Howard Hinnant74279a52010-09-04 23:28:19 +00001188#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001189 template <class _R1, class _Fp>
1190 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1191 template <class _R1, class _Fp>
1192 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001193#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001194 template <class _R1, class _Fp>
1195 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1196 template <class _R1, class _Fp>
1197 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001198#endif
1199
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001200public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001201 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001202 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001203#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001204 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001205 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001206 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1207 future(const future&) = delete;
1208 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001209 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001210 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001211 {
1212 future(std::move(__rhs)).swap(*this);
1213 return *this;
1214 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001215#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001216private:
1217 future(const future&);
1218 future& operator=(const future&);
1219public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001220#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001221 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001222 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001223 shared_future<_Rp&> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001224
1225 // retrieving the value
Howard Hinnantc834c512011-11-29 18:15:50 +00001226 _Rp& get();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001227
Howard Hinnant684902d2010-09-22 14:16:26 +00001228 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001229 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001230
1231 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001232 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001233 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001234
Howard Hinnant684902d2010-09-22 14:16:26 +00001235 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001236 void wait() const {__state_->wait();}
1237 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001238 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001239 future_status
1240 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1241 {return __state_->wait_for(__rel_time);}
1242 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001243 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001244 future_status
1245 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1246 {return __state_->wait_until(__abs_time);}
1247};
1248
Howard Hinnantc834c512011-11-29 18:15:50 +00001249template <class _Rp>
1250future<_Rp&>::future(__assoc_state<_Rp&>* __state)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001251 : __state_(__state)
1252{
Louis Dionne2c0d2262018-08-24 14:00:59 +00001253 __state_->__attach_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001254}
1255
Howard Hinnantc834c512011-11-29 18:15:50 +00001256template <class _Rp>
1257future<_Rp&>::~future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001258{
1259 if (__state_)
1260 __state_->__release_shared();
1261}
1262
Howard Hinnantc834c512011-11-29 18:15:50 +00001263template <class _Rp>
1264_Rp&
1265future<_Rp&>::get()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001266{
Howard Hinnantccdd2032010-08-30 18:46:21 +00001267 unique_ptr<__shared_count, __release_shared_count> __(__state_);
Howard Hinnantc834c512011-11-29 18:15:50 +00001268 __assoc_state<_Rp&>* __s = __state_;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001269 __state_ = nullptr;
1270 return __s->copy();
1271}
1272
1273template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001274class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001275{
1276 __assoc_sub_state* __state_;
1277
1278 explicit future(__assoc_sub_state* __state);
1279
1280 template <class> friend class promise;
Howard Hinnant92646c42010-09-03 18:39:25 +00001281 template <class> friend class shared_future;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001282
Howard Hinnant74279a52010-09-04 23:28:19 +00001283#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001284 template <class _R1, class _Fp>
1285 friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
1286 template <class _R1, class _Fp>
1287 friend future<_R1> __make_async_assoc_state(_Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001288#else
Howard Hinnantc834c512011-11-29 18:15:50 +00001289 template <class _R1, class _Fp>
1290 friend future<_R1> __make_deferred_assoc_state(_Fp __f);
1291 template <class _R1, class _Fp>
1292 friend future<_R1> __make_async_assoc_state(_Fp __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001293#endif
1294
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001295public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001296 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001297 future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant74279a52010-09-04 23:28:19 +00001298#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001300 future(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001301 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1302 future(const future&) = delete;
1303 future& operator=(const future&) = delete;
Howard Hinnant684902d2010-09-22 14:16:26 +00001304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001305 future& operator=(future&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001306 {
1307 future(std::move(__rhs)).swap(*this);
1308 return *this;
1309 }
Howard Hinnant74279a52010-09-04 23:28:19 +00001310#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001311private:
1312 future(const future&);
1313 future& operator=(const future&);
1314public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001315#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001316 ~future();
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001317 _LIBCPP_INLINE_VISIBILITY
Marshall Clow79e02112017-01-24 23:28:25 +00001318 shared_future<void> share() _NOEXCEPT;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001319
1320 // retrieving the value
1321 void get();
1322
Howard Hinnant684902d2010-09-22 14:16:26 +00001323 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001324 void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001325
1326 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00001327 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001328 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001329
Howard Hinnant684902d2010-09-22 14:16:26 +00001330 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001331 void wait() const {__state_->wait();}
1332 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00001333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001334 future_status
1335 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
1336 {return __state_->wait_for(__rel_time);}
1337 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00001338 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001339 future_status
1340 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
1341 {return __state_->wait_until(__abs_time);}
1342};
1343
Howard Hinnantc834c512011-11-29 18:15:50 +00001344template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00001345inline _LIBCPP_INLINE_VISIBILITY
1346void
Howard Hinnant22448042012-07-21 17:46:55 +00001347swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00001348{
1349 __x.swap(__y);
1350}
1351
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001352// promise<R>
1353
Howard Hinnant944510a2011-06-14 19:58:17 +00001354template <class _Callable> class packaged_task;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001355
Howard Hinnantc834c512011-11-29 18:15:50 +00001356template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001357class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001358{
Howard Hinnantc834c512011-11-29 18:15:50 +00001359 __assoc_state<_Rp>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001360
Howard Hinnant684902d2010-09-22 14:16:26 +00001361 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001362 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001363
1364 template <class> friend class packaged_task;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001365public:
1366 promise();
1367 template <class _Alloc>
1368 promise(allocator_arg_t, const _Alloc& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001369#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001371 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001372 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1373 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001374#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001375private:
1376 promise(const promise& __rhs);
1377public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001378#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001379 ~promise();
1380
1381 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001382#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001383 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001384 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001385 {
1386 promise(std::move(__rhs)).swap(*this);
1387 return *this;
1388 }
1389 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001390#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001391private:
1392 promise& operator=(const promise& __rhs);
1393public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001394#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001395 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001396 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001397
1398 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001399 future<_Rp> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001400
1401 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001402 void set_value(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001403#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001404 void set_value(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001405#endif
1406 void set_exception(exception_ptr __p);
1407
1408 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001409 void set_value_at_thread_exit(const _Rp& __r);
Howard Hinnant74279a52010-09-04 23:28:19 +00001410#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00001411 void set_value_at_thread_exit(_Rp&& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001412#endif
1413 void set_exception_at_thread_exit(exception_ptr __p);
1414};
1415
Howard Hinnantc834c512011-11-29 18:15:50 +00001416template <class _Rp>
1417promise<_Rp>::promise()
1418 : __state_(new __assoc_state<_Rp>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001419{
1420}
1421
Howard Hinnantc834c512011-11-29 18:15:50 +00001422template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001423template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001424promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001425{
Eric Fiselier0d109272014-10-23 06:24:45 +00001426 typedef __assoc_state_alloc<_Rp, _Alloc> _State;
1427 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001428 typedef __allocator_destructor<_A2> _D2;
1429 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001430 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1431 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1432 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001433}
1434
Howard Hinnantc834c512011-11-29 18:15:50 +00001435template <class _Rp>
1436promise<_Rp>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001437{
1438 if (__state_)
1439 {
1440 if (!__state_->__has_value() && __state_->use_count() > 1)
1441 __state_->set_exception(make_exception_ptr(
1442 future_error(make_error_code(future_errc::broken_promise))
1443 ));
1444 __state_->__release_shared();
1445 }
1446}
1447
Howard Hinnantc834c512011-11-29 18:15:50 +00001448template <class _Rp>
1449future<_Rp>
1450promise<_Rp>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001451{
1452 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001453 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001454 return future<_Rp>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001455}
1456
Howard Hinnantc834c512011-11-29 18:15:50 +00001457template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001458void
Howard Hinnantc834c512011-11-29 18:15:50 +00001459promise<_Rp>::set_value(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001460{
1461 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001462 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001463 __state_->set_value(__r);
1464}
1465
Howard Hinnant74279a52010-09-04 23:28:19 +00001466#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001467
Howard Hinnantc834c512011-11-29 18:15:50 +00001468template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001469void
Howard Hinnantc834c512011-11-29 18:15:50 +00001470promise<_Rp>::set_value(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001471{
1472 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001473 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001474 __state_->set_value(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001475}
1476
Howard Hinnant74279a52010-09-04 23:28:19 +00001477#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001478
Howard Hinnantc834c512011-11-29 18:15:50 +00001479template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001480void
Howard Hinnantc834c512011-11-29 18:15:50 +00001481promise<_Rp>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001482{
Marshall Clow2b36f572016-05-16 16:55:32 +00001483 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001484 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001485 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001486 __state_->set_exception(__p);
1487}
1488
Howard Hinnantc834c512011-11-29 18:15:50 +00001489template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001490void
Howard Hinnantc834c512011-11-29 18:15:50 +00001491promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001492{
1493 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001494 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001495 __state_->set_value_at_thread_exit(__r);
1496}
1497
Howard Hinnant74279a52010-09-04 23:28:19 +00001498#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001499
Howard Hinnantc834c512011-11-29 18:15:50 +00001500template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001501void
Howard Hinnantc834c512011-11-29 18:15:50 +00001502promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001503{
1504 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001505 __throw_future_error(future_errc::no_state);
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001506 __state_->set_value_at_thread_exit(_VSTD::move(__r));
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001507}
1508
Howard Hinnant74279a52010-09-04 23:28:19 +00001509#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001510
Howard Hinnantc834c512011-11-29 18:15:50 +00001511template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001512void
Howard Hinnantc834c512011-11-29 18:15:50 +00001513promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001514{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001515 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001516 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001517 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001518 __state_->set_exception_at_thread_exit(__p);
1519}
1520
1521// promise<R&>
1522
Howard Hinnantc834c512011-11-29 18:15:50 +00001523template <class _Rp>
Mehdi Amini228053d2017-05-04 17:08:54 +00001524class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001525{
Howard Hinnantc834c512011-11-29 18:15:50 +00001526 __assoc_state<_Rp&>* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001527
Howard Hinnant684902d2010-09-22 14:16:26 +00001528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001529 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001530
1531 template <class> friend class packaged_task;
1532
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001533public:
1534 promise();
1535 template <class _Allocator>
1536 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001537#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001539 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001540 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1541 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001542#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001543private:
1544 promise(const promise& __rhs);
1545public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001546#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001547 ~promise();
1548
1549 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001550#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001551 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001552 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001553 {
1554 promise(std::move(__rhs)).swap(*this);
1555 return *this;
1556 }
1557 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001558#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001559private:
1560 promise& operator=(const promise& __rhs);
1561public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001562#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001564 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001565
1566 // retrieving the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001567 future<_Rp&> get_future();
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001568
1569 // setting the result
Howard Hinnantc834c512011-11-29 18:15:50 +00001570 void set_value(_Rp& __r);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001571 void set_exception(exception_ptr __p);
1572
1573 // setting the result with deferred notification
Howard Hinnantc834c512011-11-29 18:15:50 +00001574 void set_value_at_thread_exit(_Rp&);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001575 void set_exception_at_thread_exit(exception_ptr __p);
1576};
1577
Howard Hinnantc834c512011-11-29 18:15:50 +00001578template <class _Rp>
1579promise<_Rp&>::promise()
1580 : __state_(new __assoc_state<_Rp&>)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001581{
1582}
1583
Howard Hinnantc834c512011-11-29 18:15:50 +00001584template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001585template <class _Alloc>
Howard Hinnantc834c512011-11-29 18:15:50 +00001586promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001587{
Eric Fiselier0d109272014-10-23 06:24:45 +00001588 typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
1589 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001590 typedef __allocator_destructor<_A2> _D2;
1591 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001592 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1593 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1594 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001595}
1596
Howard Hinnantc834c512011-11-29 18:15:50 +00001597template <class _Rp>
1598promise<_Rp&>::~promise()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001599{
1600 if (__state_)
1601 {
1602 if (!__state_->__has_value() && __state_->use_count() > 1)
1603 __state_->set_exception(make_exception_ptr(
1604 future_error(make_error_code(future_errc::broken_promise))
1605 ));
1606 __state_->__release_shared();
1607 }
1608}
1609
Howard Hinnantc834c512011-11-29 18:15:50 +00001610template <class _Rp>
1611future<_Rp&>
1612promise<_Rp&>::get_future()
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001613{
1614 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001615 __throw_future_error(future_errc::no_state);
Howard Hinnantc834c512011-11-29 18:15:50 +00001616 return future<_Rp&>(__state_);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001617}
1618
Howard Hinnantc834c512011-11-29 18:15:50 +00001619template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001620void
Howard Hinnantc834c512011-11-29 18:15:50 +00001621promise<_Rp&>::set_value(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001622{
1623 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001624 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001625 __state_->set_value(__r);
1626}
1627
Howard Hinnantc834c512011-11-29 18:15:50 +00001628template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001629void
Howard Hinnantc834c512011-11-29 18:15:50 +00001630promise<_Rp&>::set_exception(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001631{
Marshall Clow2b36f572016-05-16 16:55:32 +00001632 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001633 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001634 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001635 __state_->set_exception(__p);
1636}
1637
Howard Hinnantc834c512011-11-29 18:15:50 +00001638template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001639void
Howard Hinnantc834c512011-11-29 18:15:50 +00001640promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001641{
1642 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001643 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001644 __state_->set_value_at_thread_exit(__r);
1645}
1646
Howard Hinnantc834c512011-11-29 18:15:50 +00001647template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001648void
Howard Hinnantc834c512011-11-29 18:15:50 +00001649promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001650{
Eric Fiselier9dce2062016-05-31 01:50:55 +00001651 _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001652 if (__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00001653 __throw_future_error(future_errc::no_state);
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001654 __state_->set_exception_at_thread_exit(__p);
1655}
1656
1657// promise<void>
1658
1659template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00001660class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001661{
1662 __assoc_sub_state* __state_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001663
Howard Hinnant684902d2010-09-22 14:16:26 +00001664 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001665 explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00001666
1667 template <class> friend class packaged_task;
1668
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001669public:
1670 promise();
1671 template <class _Allocator>
Shoaib Meenai55f3a462017-03-02 03:22:18 +00001672 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001673 promise(allocator_arg_t, const _Allocator& __a);
Howard Hinnant74279a52010-09-04 23:28:19 +00001674#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001675 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001676 promise(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001677 : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
1678 promise(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001679#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001680private:
1681 promise(const promise& __rhs);
1682public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001683#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001684 ~promise();
1685
1686 // assignment
Howard Hinnant74279a52010-09-04 23:28:19 +00001687#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001688 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001689 promise& operator=(promise&& __rhs) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001690 {
1691 promise(std::move(__rhs)).swap(*this);
1692 return *this;
1693 }
1694 promise& operator=(const promise& __rhs) = delete;
Howard Hinnant74279a52010-09-04 23:28:19 +00001695#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001696private:
1697 promise& operator=(const promise& __rhs);
1698public:
Howard Hinnant74279a52010-09-04 23:28:19 +00001699#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00001700 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001701 void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001702
1703 // retrieving the result
1704 future<void> get_future();
1705
1706 // setting the result
1707 void set_value();
1708 void set_exception(exception_ptr __p);
1709
1710 // setting the result with deferred notification
1711 void set_value_at_thread_exit();
1712 void set_exception_at_thread_exit(exception_ptr __p);
1713};
1714
1715template <class _Alloc>
1716promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
1717{
Eric Fiselier0d109272014-10-23 06:24:45 +00001718 typedef __assoc_sub_state_alloc<_Alloc> _State;
1719 typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001720 typedef __allocator_destructor<_A2> _D2;
1721 _A2 __a(__a0);
Eric Fiselier0d109272014-10-23 06:24:45 +00001722 unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
1723 ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
1724 __state_ = _VSTD::addressof(*__hold.release());
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001725}
1726
Howard Hinnantc834c512011-11-29 18:15:50 +00001727template <class _Rp>
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001728inline _LIBCPP_INLINE_VISIBILITY
1729void
Howard Hinnant22448042012-07-21 17:46:55 +00001730swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001731{
1732 __x.swap(__y);
1733}
1734
Howard Hinnantc834c512011-11-29 18:15:50 +00001735template <class _Rp, class _Alloc>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001736 struct _LIBCPP_TEMPLATE_VIS uses_allocator<promise<_Rp>, _Alloc>
Howard Hinnant684902d2010-09-22 14:16:26 +00001737 : public true_type {};
Howard Hinnant3820f6b2010-08-27 20:10:19 +00001738
Howard Hinnantccdd2032010-08-30 18:46:21 +00001739#ifndef _LIBCPP_HAS_NO_VARIADICS
1740
1741// packaged_task
1742
1743template<class _Fp> class __packaged_task_base;
1744
Howard Hinnantc834c512011-11-29 18:15:50 +00001745template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001746class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001747{
1748 __packaged_task_base(const __packaged_task_base&);
1749 __packaged_task_base& operator=(const __packaged_task_base&);
1750public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001751 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001752 __packaged_task_base() {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001753 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00001754 virtual ~__packaged_task_base() {}
Howard Hinnant22448042012-07-21 17:46:55 +00001755 virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001756 virtual void destroy() = 0;
1757 virtual void destroy_deallocate() = 0;
Howard Hinnantc834c512011-11-29 18:15:50 +00001758 virtual _Rp operator()(_ArgTypes&& ...) = 0;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001759};
1760
1761template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
1762
Howard Hinnantc834c512011-11-29 18:15:50 +00001763template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001764class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
Howard Hinnantc834c512011-11-29 18:15:50 +00001765 : public __packaged_task_base<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001766{
Howard Hinnantc834c512011-11-29 18:15:50 +00001767 __compressed_pair<_Fp, _Alloc> __f_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001768public:
Howard Hinnant684902d2010-09-22 14:16:26 +00001769 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001770 explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001771 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001772 explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001773 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001774 __packaged_task_func(const _Fp& __f, const _Alloc& __a)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001775 : __f_(__f, __a) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001777 __packaged_task_func(_Fp&& __f, const _Alloc& __a)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001778 : __f_(_VSTD::move(__f), __a) {}
Howard Hinnant22448042012-07-21 17:46:55 +00001779 virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001780 virtual void destroy();
1781 virtual void destroy_deallocate();
Howard Hinnantc834c512011-11-29 18:15:50 +00001782 virtual _Rp operator()(_ArgTypes&& ... __args);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001783};
1784
Howard Hinnantc834c512011-11-29 18:15:50 +00001785template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001786void
Howard Hinnantc834c512011-11-29 18:15:50 +00001787__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
Howard Hinnant22448042012-07-21 17:46:55 +00001788 __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001789{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001790 ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001791}
1792
Howard Hinnantc834c512011-11-29 18:15:50 +00001793template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001794void
Howard Hinnantc834c512011-11-29 18:15:50 +00001795__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001796{
Howard Hinnantc834c512011-11-29 18:15:50 +00001797 __f_.~__compressed_pair<_Fp, _Alloc>();
Howard Hinnantccdd2032010-08-30 18:46:21 +00001798}
1799
Howard Hinnantc834c512011-11-29 18:15:50 +00001800template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001801void
Howard Hinnantc834c512011-11-29 18:15:50 +00001802__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001803{
Eric Fiselier0d109272014-10-23 06:24:45 +00001804 typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
1805 typedef allocator_traits<_Ap> _ATraits;
1806 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
Howard Hinnantc834c512011-11-29 18:15:50 +00001807 _Ap __a(__f_.second());
1808 __f_.~__compressed_pair<_Fp, _Alloc>();
Eric Fiselier0d109272014-10-23 06:24:45 +00001809 __a.deallocate(_PTraits::pointer_to(*this), 1);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001810}
1811
Howard Hinnantc834c512011-11-29 18:15:50 +00001812template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
1813_Rp
1814__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001815{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001816 return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001817}
1818
Howard Hinnant944510a2011-06-14 19:58:17 +00001819template <class _Callable> class __packaged_task_function;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001820
Howard Hinnantc834c512011-11-29 18:15:50 +00001821template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001822class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001823{
Howard Hinnantc834c512011-11-29 18:15:50 +00001824 typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
Howard Hinnant022c7482013-01-21 17:26:55 +00001825 typename aligned_storage<3*sizeof(void*)>::type __buf_;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001826 __base* __f_;
1827
1828public:
Howard Hinnantc834c512011-11-29 18:15:50 +00001829 typedef _Rp result_type;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001830
1831 // construct/copy/destroy:
Howard Hinnant684902d2010-09-22 14:16:26 +00001832 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00001833 __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
Howard Hinnantc834c512011-11-29 18:15:50 +00001834 template<class _Fp>
1835 __packaged_task_function(_Fp&& __f);
1836 template<class _Fp, class _Alloc>
1837 __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001838
Howard Hinnant22448042012-07-21 17:46:55 +00001839 __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
1840 __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001841
1842 __packaged_task_function(const __packaged_task_function&) = delete;
1843 __packaged_task_function& operator=(const __packaged_task_function&) = delete;
1844
1845 ~__packaged_task_function();
1846
Howard Hinnant22448042012-07-21 17:46:55 +00001847 void swap(__packaged_task_function&) _NOEXCEPT;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001848
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001849 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00001850 _Rp operator()(_ArgTypes...) const;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001851};
1852
Howard Hinnantc834c512011-11-29 18:15:50 +00001853template<class _Rp, class ..._ArgTypes>
Howard Hinnant22448042012-07-21 17:46:55 +00001854__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001855{
1856 if (__f.__f_ == nullptr)
1857 __f_ = nullptr;
1858 else if (__f.__f_ == (__base*)&__f.__buf_)
1859 {
1860 __f_ = (__base*)&__buf_;
1861 __f.__f_->__move_to(__f_);
1862 }
1863 else
1864 {
1865 __f_ = __f.__f_;
1866 __f.__f_ = nullptr;
1867 }
1868}
1869
Howard Hinnantc834c512011-11-29 18:15:50 +00001870template<class _Rp, class ..._ArgTypes>
1871template <class _Fp>
1872__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001873 : __f_(nullptr)
1874{
Marshall Clow733d60e2014-04-07 13:32:26 +00001875 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001876 typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001877 if (sizeof(_FF) <= sizeof(__buf_))
1878 {
1879 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001880 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001881 }
1882 else
1883 {
Howard Hinnantc834c512011-11-29 18:15:50 +00001884 typedef allocator<_FF> _Ap;
1885 _Ap __a;
1886 typedef __allocator_destructor<_Ap> _Dp;
1887 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
1888 ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001889 __f_ = __hold.release();
1890 }
1891}
1892
Howard Hinnantc834c512011-11-29 18:15:50 +00001893template<class _Rp, class ..._ArgTypes>
1894template <class _Fp, class _Alloc>
1895__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
1896 allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00001897 : __f_(nullptr)
1898{
Marshall Clow733d60e2014-04-07 13:32:26 +00001899 typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
Howard Hinnantc834c512011-11-29 18:15:50 +00001900 typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001901 if (sizeof(_FF) <= sizeof(__buf_))
1902 {
1903 __f_ = (__base*)&__buf_;
Howard Hinnantc834c512011-11-29 18:15:50 +00001904 ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
Howard Hinnantccdd2032010-08-30 18:46:21 +00001905 }
1906 else
1907 {
Eric Fiselier0d109272014-10-23 06:24:45 +00001908 typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
Howard Hinnantc834c512011-11-29 18:15:50 +00001909 _Ap __a(__a0);
1910 typedef __allocator_destructor<_Ap> _Dp;
1911 unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
Eric Fiselier0d109272014-10-23 06:24:45 +00001912 ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
1913 _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
1914 __f_ = _VSTD::addressof(*__hold.release());
Howard Hinnantccdd2032010-08-30 18:46:21 +00001915 }
1916}
1917
Howard Hinnantc834c512011-11-29 18:15:50 +00001918template<class _Rp, class ..._ArgTypes>
1919__packaged_task_function<_Rp(_ArgTypes...)>&
Howard Hinnant22448042012-07-21 17:46:55 +00001920__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001921{
1922 if (__f_ == (__base*)&__buf_)
1923 __f_->destroy();
1924 else if (__f_)
1925 __f_->destroy_deallocate();
1926 __f_ = nullptr;
1927 if (__f.__f_ == nullptr)
1928 __f_ = nullptr;
1929 else if (__f.__f_ == (__base*)&__f.__buf_)
1930 {
1931 __f_ = (__base*)&__buf_;
1932 __f.__f_->__move_to(__f_);
1933 }
1934 else
1935 {
1936 __f_ = __f.__f_;
1937 __f.__f_ = nullptr;
1938 }
Argyrios Kyrtzidisaf904652012-10-13 02:03:45 +00001939 return *this;
Howard Hinnantccdd2032010-08-30 18:46:21 +00001940}
1941
Howard Hinnantc834c512011-11-29 18:15:50 +00001942template<class _Rp, class ..._ArgTypes>
1943__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
Howard Hinnantccdd2032010-08-30 18:46:21 +00001944{
1945 if (__f_ == (__base*)&__buf_)
1946 __f_->destroy();
1947 else if (__f_)
1948 __f_->destroy_deallocate();
1949}
1950
Howard Hinnantc834c512011-11-29 18:15:50 +00001951template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001952void
Howard Hinnant22448042012-07-21 17:46:55 +00001953__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00001954{
1955 if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
1956 {
1957 typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
1958 __base* __t = (__base*)&__tempbuf;
1959 __f_->__move_to(__t);
1960 __f_->destroy();
1961 __f_ = nullptr;
1962 __f.__f_->__move_to((__base*)&__buf_);
1963 __f.__f_->destroy();
1964 __f.__f_ = nullptr;
1965 __f_ = (__base*)&__buf_;
1966 __t->__move_to((__base*)&__f.__buf_);
1967 __t->destroy();
1968 __f.__f_ = (__base*)&__f.__buf_;
1969 }
1970 else if (__f_ == (__base*)&__buf_)
1971 {
1972 __f_->__move_to((__base*)&__f.__buf_);
1973 __f_->destroy();
1974 __f_ = __f.__f_;
1975 __f.__f_ = (__base*)&__f.__buf_;
1976 }
1977 else if (__f.__f_ == (__base*)&__f.__buf_)
1978 {
1979 __f.__f_->__move_to((__base*)&__buf_);
1980 __f.__f_->destroy();
1981 __f.__f_ = __f_;
1982 __f_ = (__base*)&__buf_;
1983 }
1984 else
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001985 _VSTD::swap(__f_, __f.__f_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001986}
1987
Howard Hinnantc834c512011-11-29 18:15:50 +00001988template<class _Rp, class ..._ArgTypes>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00001989inline
Howard Hinnantc834c512011-11-29 18:15:50 +00001990_Rp
1991__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
Howard Hinnantccdd2032010-08-30 18:46:21 +00001992{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00001993 return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00001994}
1995
Howard Hinnantc834c512011-11-29 18:15:50 +00001996template<class _Rp, class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00001997class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00001998{
1999public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002000 typedef _Rp result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002001
2002private:
2003 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2004 promise<result_type> __p_;
2005
2006public:
2007 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002008 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002009 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002010 template <class _Fp,
2011 class = typename enable_if
2012 <
2013 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002014 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002015 packaged_task
2016 >::value
2017 >::type
2018 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002019 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002020 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002021 template <class _Fp, class _Allocator,
2022 class = typename enable_if
2023 <
2024 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002025 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002026 packaged_task
2027 >::value
2028 >::type
2029 >
2030 _LIBCPP_INLINE_VISIBILITY
2031 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2032 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2033 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002034 // ~packaged_task() = default;
2035
2036 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002037 packaged_task(const packaged_task&) = delete;
2038 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002039
2040 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002041 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002042 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002043 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002045 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002046 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002047 __f_ = _VSTD::move(__other.__f_);
2048 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002049 return *this;
2050 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002052 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002053 {
2054 __f_.swap(__other.__f_);
2055 __p_.swap(__other.__p_);
2056 }
2057
Howard Hinnant684902d2010-09-22 14:16:26 +00002058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002059 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002060
2061 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002063 future<result_type> get_future() {return __p_.get_future();}
2064
2065 // execution
2066 void operator()(_ArgTypes... __args);
2067 void make_ready_at_thread_exit(_ArgTypes... __args);
2068
2069 void reset();
2070};
2071
Howard Hinnantc834c512011-11-29 18:15:50 +00002072template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002073void
Howard Hinnantc834c512011-11-29 18:15:50 +00002074packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002075{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002076 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002077 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002078 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002079 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002080#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002081 try
2082 {
2083#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002084 __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002085#ifndef _LIBCPP_NO_EXCEPTIONS
2086 }
2087 catch (...)
2088 {
2089 __p_.set_exception(current_exception());
2090 }
2091#endif // _LIBCPP_NO_EXCEPTIONS
2092}
2093
Howard Hinnantc834c512011-11-29 18:15:50 +00002094template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002095void
Howard Hinnantc834c512011-11-29 18:15:50 +00002096packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002097{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002098 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002099 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002100 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002101 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002102#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002103 try
2104 {
2105#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002106 __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
Howard Hinnantccdd2032010-08-30 18:46:21 +00002107#ifndef _LIBCPP_NO_EXCEPTIONS
2108 }
2109 catch (...)
2110 {
2111 __p_.set_exception_at_thread_exit(current_exception());
2112 }
2113#endif // _LIBCPP_NO_EXCEPTIONS
2114}
2115
Howard Hinnantc834c512011-11-29 18:15:50 +00002116template<class _Rp, class ..._ArgTypes>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002117void
Howard Hinnantc834c512011-11-29 18:15:50 +00002118packaged_task<_Rp(_ArgTypes...)>::reset()
Howard Hinnantccdd2032010-08-30 18:46:21 +00002119{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002120 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002121 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002122 __p_ = promise<result_type>();
2123}
2124
2125template<class ..._ArgTypes>
Mehdi Amini228053d2017-05-04 17:08:54 +00002126class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
Howard Hinnantccdd2032010-08-30 18:46:21 +00002127{
2128public:
Eric Fiselier17f39ed2016-06-01 21:05:53 +00002129 typedef void result_type; // extension
Howard Hinnantccdd2032010-08-30 18:46:21 +00002130
2131private:
2132 __packaged_task_function<result_type(_ArgTypes...)> __f_;
2133 promise<result_type> __p_;
2134
2135public:
2136 // construction and destruction
Howard Hinnant684902d2010-09-22 14:16:26 +00002137 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002138 packaged_task() _NOEXCEPT : __p_(nullptr) {}
Marshall Clow27a55c02013-10-12 22:49:17 +00002139 template <class _Fp,
2140 class = typename enable_if
2141 <
2142 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002143 typename __uncvref<_Fp>::type,
Marshall Clow27a55c02013-10-12 22:49:17 +00002144 packaged_task
2145 >::value
2146 >::type
2147 >
Howard Hinnant684902d2010-09-22 14:16:26 +00002148 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002149 explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
Marshall Clowa0a057e2017-11-27 20:47:54 +00002150 template <class _Fp, class _Allocator,
2151 class = typename enable_if
2152 <
2153 !is_same<
Louis Dionne173f29e2019-05-29 16:01:36 +00002154 typename __uncvref<_Fp>::type,
Marshall Clowa0a057e2017-11-27 20:47:54 +00002155 packaged_task
2156 >::value
2157 >::type
Louis Dionne173f29e2019-05-29 16:01:36 +00002158 >
Marshall Clowa0a057e2017-11-27 20:47:54 +00002159 _LIBCPP_INLINE_VISIBILITY
2160 packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
2161 : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
2162 __p_(allocator_arg, __a) {}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002163 // ~packaged_task() = default;
2164
2165 // no copy
Howard Hinnantab500072012-07-21 19:34:12 +00002166 packaged_task(const packaged_task&) = delete;
2167 packaged_task& operator=(const packaged_task&) = delete;
Howard Hinnantccdd2032010-08-30 18:46:21 +00002168
2169 // move support
Howard Hinnant684902d2010-09-22 14:16:26 +00002170 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002171 packaged_task(packaged_task&& __other) _NOEXCEPT
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002172 : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002173 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002174 packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002175 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002176 __f_ = _VSTD::move(__other.__f_);
2177 __p_ = _VSTD::move(__other.__p_);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002178 return *this;
2179 }
Howard Hinnant684902d2010-09-22 14:16:26 +00002180 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002181 void swap(packaged_task& __other) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002182 {
2183 __f_.swap(__other.__f_);
2184 __p_.swap(__other.__p_);
2185 }
2186
Howard Hinnant684902d2010-09-22 14:16:26 +00002187 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002188 bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
Howard Hinnantccdd2032010-08-30 18:46:21 +00002189
2190 // result retrieval
Howard Hinnant684902d2010-09-22 14:16:26 +00002191 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantccdd2032010-08-30 18:46:21 +00002192 future<result_type> get_future() {return __p_.get_future();}
2193
2194 // execution
2195 void operator()(_ArgTypes... __args);
2196 void make_ready_at_thread_exit(_ArgTypes... __args);
2197
2198 void reset();
2199};
2200
2201template<class ..._ArgTypes>
2202void
2203packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
2204{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002205 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002206 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002207 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002208 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002209#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002210 try
2211 {
2212#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002213 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002214 __p_.set_value();
2215#ifndef _LIBCPP_NO_EXCEPTIONS
2216 }
2217 catch (...)
2218 {
2219 __p_.set_exception(current_exception());
2220 }
2221#endif // _LIBCPP_NO_EXCEPTIONS
2222}
2223
2224template<class ..._ArgTypes>
2225void
2226packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
2227{
Howard Hinnantccdd2032010-08-30 18:46:21 +00002228 if (__p_.__state_ == nullptr)
Eric Fiselier43641592015-10-02 21:25:15 +00002229 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002230 if (__p_.__state_->__has_value())
Eric Fiselier43641592015-10-02 21:25:15 +00002231 __throw_future_error(future_errc::promise_already_satisfied);
Marshall Clow7b3742d2015-09-03 15:11:32 +00002232#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantccdd2032010-08-30 18:46:21 +00002233 try
2234 {
2235#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002236 __f_(_VSTD::forward<_ArgTypes>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002237 __p_.set_value_at_thread_exit();
2238#ifndef _LIBCPP_NO_EXCEPTIONS
2239 }
2240 catch (...)
2241 {
2242 __p_.set_exception_at_thread_exit(current_exception());
2243 }
2244#endif // _LIBCPP_NO_EXCEPTIONS
2245}
2246
2247template<class ..._ArgTypes>
2248void
2249packaged_task<void(_ArgTypes...)>::reset()
2250{
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002251 if (!valid())
Eric Fiselier43641592015-10-02 21:25:15 +00002252 __throw_future_error(future_errc::no_state);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002253 __p_ = promise<result_type>();
2254}
2255
2256template <class _Callable>
2257inline _LIBCPP_INLINE_VISIBILITY
2258void
Howard Hinnant22448042012-07-21 17:46:55 +00002259swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
Howard Hinnantccdd2032010-08-30 18:46:21 +00002260{
2261 __x.swap(__y);
2262}
2263
Marshall Clowa0a057e2017-11-27 20:47:54 +00002264template <class _Callable, class _Alloc>
2265struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
2266 : public true_type {};
2267
Howard Hinnantc834c512011-11-29 18:15:50 +00002268template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002269_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant74279a52010-09-04 23:28:19 +00002270#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002271__make_deferred_assoc_state(_Fp&& __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002272#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002273__make_deferred_assoc_state(_Fp __f)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002274#endif
2275{
Howard Hinnantc834c512011-11-29 18:15:50 +00002276 unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
2277 __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2278 return future<_Rp>(__h.get());
Howard Hinnantccdd2032010-08-30 18:46:21 +00002279}
2280
Howard Hinnantc834c512011-11-29 18:15:50 +00002281template <class _Rp, class _Fp>
Louis Dionne3b967d02019-12-10 18:00:42 -05002282_LIBCPP_INLINE_VISIBILITY future<_Rp>
Howard Hinnant95cfd872011-05-19 15:05:04 +00002283#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc834c512011-11-29 18:15:50 +00002284__make_async_assoc_state(_Fp&& __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002285#else
Howard Hinnantc834c512011-11-29 18:15:50 +00002286__make_async_assoc_state(_Fp __f)
Howard Hinnant95cfd872011-05-19 15:05:04 +00002287#endif
2288{
Howard Hinnantc834c512011-11-29 18:15:50 +00002289 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
2290 __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
2291 _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
2292 return future<_Rp>(__h.get());
Howard Hinnant95cfd872011-05-19 15:05:04 +00002293}
2294
Howard Hinnantc834c512011-11-29 18:15:50 +00002295template <class _Fp, class... _Args>
Louis Dionne3b967d02019-12-10 18:00:42 -05002296class _LIBCPP_HIDDEN __async_func
Howard Hinnant95cfd872011-05-19 15:05:04 +00002297{
Howard Hinnantc834c512011-11-29 18:15:50 +00002298 tuple<_Fp, _Args...> __f_;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002299
2300public:
Howard Hinnantc834c512011-11-29 18:15:50 +00002301 typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
Howard Hinnant95cfd872011-05-19 15:05:04 +00002302
2303 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002304 explicit __async_func(_Fp&& __f, _Args&&... __args)
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002305 : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002306
2307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002308 __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
Howard Hinnant95cfd872011-05-19 15:05:04 +00002309
Howard Hinnantc834c512011-11-29 18:15:50 +00002310 _Rp operator()()
Howard Hinnant95cfd872011-05-19 15:05:04 +00002311 {
2312 typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
2313 return __execute(_Index());
2314 }
2315private:
2316 template <size_t ..._Indices>
Howard Hinnantc834c512011-11-29 18:15:50 +00002317 _Rp
Howard Hinnant95cfd872011-05-19 15:05:04 +00002318 __execute(__tuple_indices<_Indices...>)
2319 {
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002320 return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
Howard Hinnant95cfd872011-05-19 15:05:04 +00002321 }
2322};
2323
Marshall Clowd56a5b62013-11-03 22:06:53 +00002324inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
Marshall Clow335b7992013-11-03 15:43:35 +00002325{ return (int(__policy) & int(__value)) != 0; }
2326
Howard Hinnantc834c512011-11-29 18:15:50 +00002327template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002328_LIBCPP_NODISCARD_AFTER_CXX17
Howard Hinnantc834c512011-11-29 18:15:50 +00002329future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2330async(launch __policy, _Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002331{
Howard Hinnantc834c512011-11-29 18:15:50 +00002332 typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
2333 typedef typename _BF::_Rp _Rp;
Marshall Clow335b7992013-11-03 15:43:35 +00002334
2335#ifndef _LIBCPP_NO_EXCEPTIONS
2336 try
2337 {
2338#endif
2339 if (__does_policy_contain(__policy, launch::async))
2340 return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002341 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002342#ifndef _LIBCPP_NO_EXCEPTIONS
2343 }
2344 catch ( ... ) { if (__policy == launch::async) throw ; }
2345#endif
2346
2347 if (__does_policy_contain(__policy, launch::deferred))
2348 return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002349 __decay_copy(_VSTD::forward<_Args>(__args))...));
Marshall Clow335b7992013-11-03 15:43:35 +00002350 return future<_Rp>{};
Howard Hinnantccdd2032010-08-30 18:46:21 +00002351}
2352
Howard Hinnantc834c512011-11-29 18:15:50 +00002353template <class _Fp, class... _Args>
Marshall Clow6ac349c2017-11-23 01:25:03 +00002354_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002355future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
2356async(_Fp&& __f, _Args&&... __args)
Howard Hinnantccdd2032010-08-30 18:46:21 +00002357{
Howard Hinnantc834c512011-11-29 18:15:50 +00002358 return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002359 _VSTD::forward<_Args>(__args)...);
Howard Hinnantccdd2032010-08-30 18:46:21 +00002360}
2361
2362#endif // _LIBCPP_HAS_NO_VARIADICS
2363
Howard Hinnante6a10852010-09-03 21:46:37 +00002364// shared_future
2365
Howard Hinnantc834c512011-11-29 18:15:50 +00002366template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002367class _LIBCPP_TEMPLATE_VIS shared_future
Howard Hinnant92646c42010-09-03 18:39:25 +00002368{
Howard Hinnantc834c512011-11-29 18:15:50 +00002369 __assoc_state<_Rp>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002370
2371public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002372 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002373 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002374 _LIBCPP_INLINE_VISIBILITY
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002375 shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002376 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002377#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002378 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002379 shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002380 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002381 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002382 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002383 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002384#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002385 ~shared_future();
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002386 shared_future& operator=(const shared_future& __rhs) _NOEXCEPT;
Howard Hinnant74279a52010-09-04 23:28:19 +00002387#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002389 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002390 {
2391 shared_future(std::move(__rhs)).swap(*this);
2392 return *this;
2393 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002394#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002395
2396 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002397 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002398 const _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002399
Howard Hinnant684902d2010-09-22 14:16:26 +00002400 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002401 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002402
2403 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002405 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002406
Howard Hinnant684902d2010-09-22 14:16:26 +00002407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002408 void wait() const {__state_->wait();}
2409 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002411 future_status
2412 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2413 {return __state_->wait_for(__rel_time);}
2414 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002415 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002416 future_status
2417 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2418 {return __state_->wait_until(__abs_time);}
2419};
2420
Howard Hinnantc834c512011-11-29 18:15:50 +00002421template <class _Rp>
2422shared_future<_Rp>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002423{
2424 if (__state_)
2425 __state_->__release_shared();
2426}
2427
Howard Hinnantc834c512011-11-29 18:15:50 +00002428template <class _Rp>
2429shared_future<_Rp>&
Marshall Clow6f9c48b2016-11-14 19:58:05 +00002430shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002431{
2432 if (__rhs.__state_)
2433 __rhs.__state_->__add_shared();
2434 if (__state_)
2435 __state_->__release_shared();
2436 __state_ = __rhs.__state_;
2437 return *this;
2438}
2439
Howard Hinnantc834c512011-11-29 18:15:50 +00002440template <class _Rp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00002441class _LIBCPP_TEMPLATE_VIS shared_future<_Rp&>
Howard Hinnant92646c42010-09-03 18:39:25 +00002442{
Howard Hinnantc834c512011-11-29 18:15:50 +00002443 __assoc_state<_Rp&>* __state_;
Howard Hinnant92646c42010-09-03 18:39:25 +00002444
2445public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002447 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002449 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2450 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002451#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002453 shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002454 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002455 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002456 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002457 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002458#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002459 ~shared_future();
2460 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002461#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002462 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002463 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002464 {
2465 shared_future(std::move(__rhs)).swap(*this);
2466 return *this;
2467 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002468#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002469
2470 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc834c512011-11-29 18:15:50 +00002472 _Rp& get() const {return __state_->copy();}
Howard Hinnant92646c42010-09-03 18:39:25 +00002473
Howard Hinnant684902d2010-09-22 14:16:26 +00002474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002475 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002476
2477 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002479 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002480
Howard Hinnant684902d2010-09-22 14:16:26 +00002481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002482 void wait() const {__state_->wait();}
2483 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002485 future_status
2486 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2487 {return __state_->wait_for(__rel_time);}
2488 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002489 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002490 future_status
2491 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2492 {return __state_->wait_until(__abs_time);}
2493};
2494
Howard Hinnantc834c512011-11-29 18:15:50 +00002495template <class _Rp>
2496shared_future<_Rp&>::~shared_future()
Howard Hinnant92646c42010-09-03 18:39:25 +00002497{
2498 if (__state_)
2499 __state_->__release_shared();
2500}
2501
Howard Hinnantc834c512011-11-29 18:15:50 +00002502template <class _Rp>
2503shared_future<_Rp&>&
2504shared_future<_Rp&>::operator=(const shared_future& __rhs)
Howard Hinnant92646c42010-09-03 18:39:25 +00002505{
2506 if (__rhs.__state_)
2507 __rhs.__state_->__add_shared();
2508 if (__state_)
2509 __state_->__release_shared();
2510 __state_ = __rhs.__state_;
2511 return *this;
2512}
2513
2514template <>
Mehdi Amini228053d2017-05-04 17:08:54 +00002515class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
Howard Hinnant92646c42010-09-03 18:39:25 +00002516{
2517 __assoc_sub_state* __state_;
2518
2519public:
Howard Hinnant684902d2010-09-22 14:16:26 +00002520 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002521 shared_future() _NOEXCEPT : __state_(nullptr) {}
Howard Hinnant684902d2010-09-22 14:16:26 +00002522 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002523 shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
2524 {if (__state_) __state_->__add_shared();}
Howard Hinnant74279a52010-09-04 23:28:19 +00002525#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002526 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002527 shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002528 {__f.__state_ = nullptr;}
Howard Hinnant684902d2010-09-22 14:16:26 +00002529 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002530 shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
Howard Hinnant92646c42010-09-03 18:39:25 +00002531 {__rhs.__state_ = nullptr;}
Howard Hinnant74279a52010-09-04 23:28:19 +00002532#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002533 ~shared_future();
2534 shared_future& operator=(const shared_future& __rhs);
Howard Hinnant74279a52010-09-04 23:28:19 +00002535#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant684902d2010-09-22 14:16:26 +00002536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002537 shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002538 {
2539 shared_future(std::move(__rhs)).swap(*this);
2540 return *this;
2541 }
Howard Hinnant74279a52010-09-04 23:28:19 +00002542#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnant92646c42010-09-03 18:39:25 +00002543
2544 // retrieving the value
Howard Hinnant684902d2010-09-22 14:16:26 +00002545 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002546 void get() const {__state_->copy();}
2547
Howard Hinnant684902d2010-09-22 14:16:26 +00002548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002549 void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
Howard Hinnant92646c42010-09-03 18:39:25 +00002550
2551 // functions to check state
Howard Hinnant684902d2010-09-22 14:16:26 +00002552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant22448042012-07-21 17:46:55 +00002553 bool valid() const _NOEXCEPT {return __state_ != nullptr;}
Howard Hinnant92646c42010-09-03 18:39:25 +00002554
Howard Hinnant684902d2010-09-22 14:16:26 +00002555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002556 void wait() const {__state_->wait();}
2557 template <class _Rep, class _Period>
Howard Hinnant684902d2010-09-22 14:16:26 +00002558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002559 future_status
2560 wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
2561 {return __state_->wait_for(__rel_time);}
2562 template <class _Clock, class _Duration>
Howard Hinnant684902d2010-09-22 14:16:26 +00002563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant92646c42010-09-03 18:39:25 +00002564 future_status
2565 wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
2566 {return __state_->wait_until(__abs_time);}
2567};
2568
Howard Hinnantc834c512011-11-29 18:15:50 +00002569template <class _Rp>
Howard Hinnant92646c42010-09-03 18:39:25 +00002570inline _LIBCPP_INLINE_VISIBILITY
2571void
Howard Hinnant22448042012-07-21 17:46:55 +00002572swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
Howard Hinnant92646c42010-09-03 18:39:25 +00002573{
2574 __x.swap(__y);
2575}
2576
Howard Hinnantc834c512011-11-29 18:15:50 +00002577template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002578inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002579shared_future<_Rp>
Marshall Clow79e02112017-01-24 23:28:25 +00002580future<_Rp>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002581{
Howard Hinnantc834c512011-11-29 18:15:50 +00002582 return shared_future<_Rp>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002583}
2584
Howard Hinnantc834c512011-11-29 18:15:50 +00002585template <class _Rp>
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002586inline
Howard Hinnantc834c512011-11-29 18:15:50 +00002587shared_future<_Rp&>
Marshall Clow79e02112017-01-24 23:28:25 +00002588future<_Rp&>::share() _NOEXCEPT
Howard Hinnante6a10852010-09-03 21:46:37 +00002589{
Howard Hinnantc834c512011-11-29 18:15:50 +00002590 return shared_future<_Rp&>(_VSTD::move(*this));
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002591}
2592
Howard Hinnante65e8e32010-12-02 16:45:21 +00002593#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
2594
Evgeniy Stepanov2fb1cb62015-11-07 01:22:13 +00002595inline
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002596shared_future<void>
Marshall Clow79e02112017-01-24 23:28:25 +00002597future<void>::share() _NOEXCEPT
Howard Hinnant9a7d09c2010-11-30 20:23:32 +00002598{
Howard Hinnantb1ad5a82011-06-30 21:18:19 +00002599 return shared_future<void>(_VSTD::move(*this));
Howard Hinnante6a10852010-09-03 21:46:37 +00002600}
2601
Howard Hinnante65e8e32010-12-02 16:45:21 +00002602#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2603
Howard Hinnantc51e1022010-05-11 19:42:16 +00002604_LIBCPP_END_NAMESPACE_STD
2605
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00002606#endif // !_LIBCPP_HAS_NO_THREADS
2607
Howard Hinnantc51e1022010-05-11 19:42:16 +00002608#endif // _LIBCPP_FUTURE