aboutsummaryrefslogtreecommitdiff
path: root/tests/libcxx/include/future
diff options
context:
space:
mode:
Diffstat (limited to 'tests/libcxx/include/future')
-rw-r--r--tests/libcxx/include/future2313
1 files changed, 2313 insertions, 0 deletions
diff --git a/tests/libcxx/include/future b/tests/libcxx/include/future
new file mode 100644
index 00000000..3be5f052
--- /dev/null
+++ b/tests/libcxx/include/future
@@ -0,0 +1,2313 @@
+// -*- C++ -*-
+//===--------------------------- future -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FUTURE
+#define _LIBCPP_FUTURE
+
+/*
+ future synopsis
+
+namespace std
+{
+
+enum class future_errc
+{
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+};
+
+enum class launch
+{
+ async = 1,
+ deferred = 2,
+ any = async | deferred
+};
+
+enum class future_status
+{
+ ready,
+ timeout,
+ deferred
+};
+
+template <> struct is_error_code_enum<future_errc> : public true_type { };
+error_code make_error_code(future_errc e);
+error_condition make_error_condition(future_errc e);
+
+const error_category& future_category();
+
+class future_error
+ : public logic_error
+{
+public:
+ future_error(error_code ec); // exposition only
+
+ const error_code& code() const throw();
+ const char* what() const throw();
+};
+
+template <class R>
+class promise
+{
+public:
+ promise();
+ template <class Allocator>
+ promise(allocator_arg_t, const Allocator& a);
+ promise(promise&& rhs);
+ promise(const promise& rhs) = delete;
+ ~promise();
+
+ // assignment
+ promise& operator=(promise&& rhs);
+ promise& operator=(const promise& rhs) = delete;
+ void swap(promise& other);
+
+ // retrieving the result
+ future<R> get_future();
+
+ // setting the result
+ void set_value(const R& r);
+ void set_value(R&& r);
+ void set_exception(exception_ptr p);
+
+ // setting the result with deferred notification
+ void set_value_at_thread_exit(const R& r);
+ void set_value_at_thread_exit(R&& r);
+ void set_exception_at_thread_exit(exception_ptr p);
+};
+
+template <class R>
+class promise<R&>
+{
+public:
+ promise();
+ template <class Allocator>
+ promise(allocator_arg_t, const Allocator& a);
+ promise(promise&& rhs);
+ promise(const promise& rhs) = delete;
+ ~promise();
+
+ // assignment
+ promise& operator=(promise&& rhs);
+ promise& operator=(const promise& rhs) = delete;
+ void swap(promise& other);
+
+ // retrieving the result
+ future<R&> get_future();
+
+ // setting the result
+ void set_value(R& r);
+ void set_exception(exception_ptr p);
+
+ // setting the result with deferred notification
+ void set_value_at_thread_exit(R&);
+ void set_exception_at_thread_exit(exception_ptr p);
+};
+
+template <>
+class promise<void>
+{
+public:
+ promise();
+ template <class Allocator>
+ promise(allocator_arg_t, const Allocator& a);
+ promise(promise&& rhs);
+ promise(const promise& rhs) = delete;
+ ~promise();
+
+ // assignment
+ promise& operator=(promise&& rhs);
+ promise& operator=(const promise& rhs) = delete;
+ void swap(promise& other);
+
+ // retrieving the result
+ future<void> get_future();
+
+ // setting the result
+ void set_value();
+ void set_exception(exception_ptr p);
+
+ // setting the result with deferred notification
+ void set_value_at_thread_exit();
+ void set_exception_at_thread_exit(exception_ptr p);
+};
+
+template <class R> void swap(promise<R>& x, promise<R>& y);
+
+template <class R, class Alloc>
+ struct uses_allocator<promise<R>, Alloc> : public true_type {};
+
+template <class R>
+class future
+{
+public:
+ future();
+ future(future&&);
+ future(const future& rhs) = delete;
+ ~future();
+ future& operator=(const future& rhs) = delete;
+ future& operator=(future&&);
+ shared_future<R> share() &&;
+
+ // retrieving the value
+ R get();
+
+ // functions to check state
+ bool valid() const;
+
+ void wait() const;
+ template <class Rep, class Period>
+ future_status
+ wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class R>
+class future<R&>
+{
+public:
+ future();
+ future(future&&);
+ future(const future& rhs) = delete;
+ ~future();
+ future& operator=(const future& rhs) = delete;
+ future& operator=(future&&);
+ shared_future<R&> share() &&;
+
+ // retrieving the value
+ R& get();
+
+ // functions to check state
+ bool valid() const;
+
+ void wait() const;
+ template <class Rep, class Period>
+ future_status
+ wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <>
+class future<void>
+{
+public:
+ future();
+ future(future&&);
+ future(const future& rhs) = delete;
+ ~future();
+ future& operator=(const future& rhs) = delete;
+ future& operator=(future&&);
+ shared_future<void> share() &&;
+
+ // retrieving the value
+ void get();
+
+ // functions to check state
+ bool valid() const;
+
+ void wait() const;
+ template <class Rep, class Period>
+ future_status
+ wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class R>
+class shared_future
+{
+public:
+ shared_future();
+ shared_future(const shared_future& rhs);
+ shared_future(future<R>&&);
+ shared_future(shared_future&& rhs);
+ ~shared_future();
+ shared_future& operator=(const shared_future& rhs);
+ shared_future& operator=(shared_future&& rhs);
+
+ // retrieving the value
+ const R& get() const;
+
+ // functions to check state
+ bool valid() const;
+
+ void wait() const;
+ template <class Rep, class Period>
+ future_status
+ wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class R>
+class shared_future<R&>
+{
+public:
+ shared_future();
+ shared_future(const shared_future& rhs);
+ shared_future(future<R&>&&);
+ shared_future(shared_future&& rhs);
+ ~shared_future();
+ shared_future& operator=(const shared_future& rhs);
+ shared_future& operator=(shared_future&& rhs);
+
+ // retrieving the value
+ R& get() const;
+
+ // functions to check state
+ bool valid() const;
+
+ void wait() const;
+ template <class Rep, class Period>
+ future_status
+ wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <>
+class shared_future<void>
+{
+public:
+ shared_future();
+ shared_future(const shared_future& rhs);
+ shared_future(future<void>&&);
+ shared_future(shared_future&& rhs);
+ ~shared_future();
+ shared_future& operator=(const shared_future& rhs);
+ shared_future& operator=(shared_future&& rhs);
+
+ // retrieving the value
+ void get() const;
+
+ // functions to check state
+ bool valid() const;
+
+ void wait() const;
+ template <class Rep, class Period>
+ future_status
+ wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status
+ wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class F, class... Args>
+ future<typename result_of<F(Args...)>::type>
+ async(F&& f, Args&&... args);
+
+template <class F, class... Args>
+ future<typename result_of<F(Args...)>::type>
+ async(launch policy, F&& f, Args&&... args);
+
+template <class> class packaged_task; // undefined
+
+template <class R, class... ArgTypes>
+class packaged_task<R(ArgTypes...)>
+{
+public:
+ typedef R result_type;
+
+ // construction and destruction
+ packaged_task();
+ template <class F>
+ explicit packaged_task(F&& f);
+ template <class F, class Allocator>
+ explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+ ~packaged_task();
+
+ // no copy
+ packaged_task(packaged_task&) = delete;
+ packaged_task& operator=(packaged_task&) = delete;
+
+ // move support
+ packaged_task(packaged_task&& other);
+ packaged_task& operator=(packaged_task&& other);
+ void swap(packaged_task& other);
+
+ bool valid() const;
+
+ // result retrieval
+ future<R> get_future();
+
+ // execution
+ void operator()(ArgTypes... );
+ void make_ready_at_thread_exit(ArgTypes...);
+
+ void reset();
+};
+
+template <class R>
+ void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&);
+
+template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
+
+} // std
+
+*/
+
+#include <__config>
+#include <system_error>
+#include <memory>
+#include <chrono>
+#include <exception>
+#include <mutex>
+#include <thread>
+
+#pragma GCC system_header
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+//enum class future_errc
+struct _LIBCPP_VISIBLE future_errc
+{
+enum _ {
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+};
+
+ _ __v_;
+
+ _LIBCPP_INLINE_VISIBILITY future_errc(_ __v) : __v_(__v) {}
+ _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
+
+};
+
+template <>
+struct _LIBCPP_VISIBLE is_error_code_enum<future_errc> : public true_type {};
+
+//enum class launch
+struct _LIBCPP_VISIBLE launch
+{
+enum _ {
+ async = 1,
+ deferred = 2,
+ any = async | deferred
+};
+
+ _ __v_;
+
+ _LIBCPP_INLINE_VISIBILITY launch(_ __v) : __v_(__v) {}
+ _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
+
+};
+
+//enum class future_status
+struct _LIBCPP_VISIBLE future_status
+{
+enum _ {
+ ready,
+ timeout,
+ deferred
+};
+
+ _ __v_;
+
+ _LIBCPP_INLINE_VISIBILITY future_status(_ __v) : __v_(__v) {}
+ _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;}
+
+};
+
+_LIBCPP_VISIBLE
+const error_category& future_category();
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_code
+make_error_code(future_errc __e)
+{
+ return error_code(static_cast<int>(__e), future_category());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_condition
+make_error_condition(future_errc __e)
+{
+ return error_condition(static_cast<int>(__e), future_category());
+}
+
+class _LIBCPP_EXCEPTION_ABI future_error
+ : public logic_error
+{
+ error_code __ec_;
+public:
+ future_error(error_code __ec);
+
+ _LIBCPP_INLINE_VISIBILITY
+ const error_code& code() const throw() {return __ec_;}
+};
+
+class __assoc_sub_state
+ : public __shared_count
+{
+protected:
+ exception_ptr __exception_;
+ mutable mutex __mut_;
+ mutable condition_variable __cv_;
+ unsigned __state_;
+
+ virtual void __on_zero_shared();
+ void __sub_wait(unique_lock<mutex>& __lk);
+public:
+ enum
+ {
+ __constructed = 1,
+ __future_attached = 2,
+ ready = 4,
+ deferred = 8
+ };
+
+ _LIBCPP_INLINE_VISIBILITY
+ __assoc_sub_state() : __state_(0) {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool __has_value() const
+ {return (__state_ & __constructed) || (__exception_ != nullptr);}
+
+ _LIBCPP_INLINE_VISIBILITY
+ void __set_future_attached() {__state_ |= __future_attached;}
+ _LIBCPP_INLINE_VISIBILITY
+ bool __has_future_attached() const {return __state_ & __future_attached;}
+
+ _LIBCPP_INLINE_VISIBILITY
+ void __set_deferred() {__state_ |= deferred;}
+
+ void __make_ready();
+ _LIBCPP_INLINE_VISIBILITY
+ bool __is_ready() const {return __state_ & ready;}
+
+ void set_value();
+ void set_value_at_thread_exit();
+
+ void set_exception(exception_ptr __p);
+ void set_exception_at_thread_exit(exception_ptr __p);
+
+ void copy();
+
+ void wait();
+ template <class _Rep, class _Period>
+ future_status
+ wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
+ template <class _Clock, class _Duration>
+ future_status
+ wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
+
+ virtual void __execute();
+};
+
+template <class _Clock, class _Duration>
+future_status
+__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+{
+ unique_lock<mutex> __lk(__mut_);
+ if (__state_ & deferred)
+ return future_status::deferred;
+ while (!(__state_ & ready) && _Clock::now() < __abs_time)
+ __cv_.wait_until(__lk, __abs_time);
+ if (__state_ & ready)
+ return future_status::ready;
+ return future_status::timeout;
+}
+
+template <class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY
+future_status
+__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+{
+ return wait_until(chrono::steady_clock::now() + __rel_time);
+}
+
+template <class _R>
+class __assoc_state
+ : public __assoc_sub_state
+{
+ typedef __assoc_sub_state base;
+ typedef typename aligned_storage<sizeof(_R), alignment_of<_R>::value>::type _U;
+protected:
+ _U __value_;
+
+ virtual void __on_zero_shared();
+public:
+
+ template <class _Arg>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void set_value(_Arg&& __arg);
+#else
+ void set_value(_Arg& __arg);
+#endif
+
+ template <class _Arg>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void set_value_at_thread_exit(_Arg&& __arg);
+#else
+ void set_value_at_thread_exit(_Arg& __arg);
+#endif
+
+ _R move();
+ typename add_lvalue_reference<_R>::type copy();
+};
+
+template <class _R>
+void
+__assoc_state<_R>::__on_zero_shared()
+{
+ if (this->__state_ & base::__constructed)
+ reinterpret_cast<_R*>(&__value_)->~_R();
+ delete this;
+}
+
+template <class _R>
+template <class _Arg>
+void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__assoc_state<_R>::set_value(_Arg&& __arg)
+#else
+__assoc_state<_R>::set_value(_Arg& __arg)
+#endif
+{
+ unique_lock<mutex> __lk(this->__mut_);
+ if (this->__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
+ this->__state_ |= base::__constructed | base::ready;
+ __lk.unlock();
+ __cv_.notify_all();
+}
+
+template <class _R>
+template <class _Arg>
+void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__assoc_state<_R>::set_value_at_thread_exit(_Arg&& __arg)
+#else
+__assoc_state<_R>::set_value_at_thread_exit(_Arg& __arg)
+#endif
+{
+ unique_lock<mutex> __lk(this->__mut_);
+ if (this->__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ ::new(&__value_) _R(_STD::forward<_Arg>(__arg));
+ this->__state_ |= base::__constructed;
+ __thread_local_data()->__make_ready_at_thread_exit(this);
+ __lk.unlock();
+}
+
+template <class _R>
+_R
+__assoc_state<_R>::move()
+{
+ unique_lock<mutex> __lk(this->__mut_);
+ this->__sub_wait(__lk);
+ if (this->__exception_ != nullptr)
+ rethrow_exception(this->__exception_);
+ return _STD::move(*reinterpret_cast<_R*>(&__value_));
+}
+
+template <class _R>
+typename add_lvalue_reference<_R>::type
+__assoc_state<_R>::copy()
+{
+ unique_lock<mutex> __lk(this->__mut_);
+ this->__sub_wait(__lk);
+ if (this->__exception_ != nullptr)
+ rethrow_exception(this->__exception_);
+ return *reinterpret_cast<_R*>(&__value_);
+}
+
+template <class _R>
+class __assoc_state<_R&>
+ : public __assoc_sub_state
+{
+ typedef __assoc_sub_state base;
+ typedef _R* _U;
+protected:
+ _U __value_;
+
+ virtual void __on_zero_shared();
+public:
+
+ void set_value(_R& __arg);
+ void set_value_at_thread_exit(_R& __arg);
+
+ _R& copy();
+};
+
+template <class _R>
+void
+__assoc_state<_R&>::__on_zero_shared()
+{
+ delete this;
+}
+
+template <class _R>
+void
+__assoc_state<_R&>::set_value(_R& __arg)
+{
+ unique_lock<mutex> __lk(this->__mut_);
+ if (this->__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ __value_ = &__arg;
+ this->__state_ |= base::__constructed | base::ready;
+ __lk.unlock();
+ __cv_.notify_all();
+}
+
+template <class _R>
+void
+__assoc_state<_R&>::set_value_at_thread_exit(_R& __arg)
+{
+ unique_lock<mutex> __lk(this->__mut_);
+ if (this->__has_value())
+ throw future_error(make_error_code(future_errc::promise_already_satisfied));
+ __value_ = &__arg;
+ this->__state_ |= base::__constructed;
+ __thread_local_data()->__make_ready_at_thread_exit(this);
+ __lk.unlock();
+}
+
+template <class _R>
+_R&
+__assoc_state<_R&>::copy()
+{
+ unique_lock<mutex> __lk(this->__mut_);
+ this->__sub_wait(__lk);
+ if (this->__exception_ != nullptr)
+ rethrow_exception(this->__exception_);
+ return *__value_;
+}
+
+template <class _R, class _Alloc>
+class __assoc_state_alloc
+ : public __assoc_state<_R>
+{
+ typedef __assoc_state<_R> base;
+ _Alloc __alloc_;
+
+ virtual void __on_zero_shared();
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __assoc_state_alloc(const _Alloc& __a)
+ : __alloc_(__a) {}
+};
+
+template <class _R, class _Alloc>
+void
+__assoc_state_alloc<_R, _Alloc>::__on_zero_shared()
+{
+ if (this->__state_ & base::__constructed)
+ reinterpret_cast<_R*>(&this->__value_)->~_R();
+ typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+ this->~__assoc_state_alloc();
+ __a.deallocate(this, 1);
+}
+
+template <class _R, class _Alloc>
+class __assoc_state_alloc<_R&, _Alloc>
+ : public __assoc_state<_R&>
+{
+ typedef __assoc_state<_R&> base;
+ _Alloc __alloc_;
+
+ virtual void __on_zero_shared();
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __assoc_state_alloc(const _Alloc& __a)
+ : __alloc_(__a) {}
+};
+
+template <class _R, class _Alloc>
+void
+__assoc_state_alloc<_R&, _Alloc>::__on_zero_shared()
+{
+ typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+ this->~__assoc_state_alloc();
+ __a.deallocate(this, 1);
+}
+
+template <class _Alloc>
+class __assoc_sub_state_alloc
+ : public __assoc_sub_state
+{
+ typedef __assoc_sub_state base;
+ _Alloc __alloc_;
+
+ virtual void __on_zero_shared();
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __assoc_sub_state_alloc(const _Alloc& __a)
+ : __alloc_(__a) {}
+};
+
+template <class _Alloc>
+void
+__assoc_sub_state_alloc<_Alloc>::__on_zero_shared()
+{
+ this->~base();
+ typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
+ this->~__assoc_sub_state_alloc();
+ __a.deallocate(this, 1);
+}
+
+template <class _R, class _F>
+class __deferred_assoc_state
+ : public __assoc_state<_R>
+{
+ typedef __assoc_state<_R> base;
+
+ _F __func_;
+
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ explicit __deferred_assoc_state(_F&& __f);
+#endif
+
+ virtual void __execute();
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _R, class _F>
+inline _LIBCPP_INLINE_VISIBILITY
+__deferred_assoc_state<_R, _F>::__deferred_assoc_state(_F&& __f)
+ : __func_(_STD::forward<_F>(__f))
+{
+ this->__set_deferred();
+}
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _R, class _F>
+void
+__deferred_assoc_state<_R, _F>::__execute()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try
+ {
+#endif // _LIBCPP_NO_EXCEPTIONS
+ this->set_value(__func_());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ }
+ catch (...)
+ {
+ this->set_exception(current_exception());
+ }
+#endif // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _F>
+class __deferred_assoc_state<void, _F>
+ : public __assoc_sub_state
+{
+ typedef __assoc_sub_state base;
+
+ _F __func_;
+
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ explicit __deferred_assoc_state(_F&& __f);
+#endif
+
+ virtual void __execute();
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _F>
+inline _LIBCPP_INLINE_VISIBILITY
+__deferred_assoc_state<void, _F>::__deferred_assoc_state(_F&& __f)
+ : __func_(_STD::forward<_F>(__f))
+{
+ this->__set_deferred();
+}
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _F>
+void
+__deferred_assoc_state<void, _F>::__execute()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try
+ {
+#endif // _LIBCPP_NO_EXCEPTIONS
+ __func_();
+ this->set_value();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ }
+ catch (...)
+ {
+ this->set_exception(current_exception());
+ }
+#endif // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class> class promise;
+template <class> class shared_future;
+template <class> class atomic_future;
+
+// future
+
+template <class _R> class future;
+
+template <class _R, class _F>
+future<_R>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__make_deferred_assoc_state(_F&& __f);
+#else
+__make_deferred_assoc_state(_F __f);
+#endif
+
+template <class _R>
+class _LIBCPP_VISIBLE future
+{
+ __assoc_state<_R>* __state_;
+
+ explicit future(__assoc_state<_R>* __state);
+
+ template <class> friend class promise;
+ template <class> friend class shared_future;
+ template <class> friend class atomic_future;
+
+ template <class _R1, class _F>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ friend future<_R1> __make_deferred_assoc_state(_F&& __f);
+#else
+ friend future<_R1> __make_deferred_assoc_state(_F __f);
+#endif
+
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ future() : __state_(nullptr) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ _LIBCPP_INLINE_VISIBILITY
+ future(future&& __rhs)
+ : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+ future(const future&) = delete;
+ future& operator=(const future&) = delete;
+ _LIBCPP_INLINE_VISIBILITY
+ future& operator=(future&& __rhs)
+ {
+ future(std::move(__rhs)).swap(*this);
+ return *this;
+ }
+#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+ future(const future&);
+ future& operator=(const future&);
+public:
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ ~future();
+ shared_future<_R> share();
+
+ // retrieving the value
+ _R get();
+
+ _LIBCPP_INLINE_VISIBILITY
+ void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
+
+ // functions to check state
+ _LIBCPP_INLINE_VISIBILITY
+ bool valid() const {return __state_ != nullptr;}
+
+ _LIBCPP_INLINE_VISIBILITY
+ void wait() const {__state_->wait();}
+ template <class _Rep, class _Period>
+ _LIBCPP_INLINE_VISIBILITY
+ future_status
+ wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+ {return __state_->wait_for(__rel_time);}
+ template <class _Clock, class _Duration>
+ _LIBCPP_INLINE_VISIBILITY
+ future_status
+ wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+ {return __state_->wait_until(__abs_time);}
+};
+
+template <class _R>
+future<_R>::future(__assoc_state<_R>* __state)
+ : __state_(__state)
+{
+ if (__state_->__has_future_attached())
+ throw future_error(make_error_code(future_errc::future_already_retrieved));
+ __state_->__add_shared();
+ __state_->__set_future_attached();
+}
+
+struct __release_shared_count
+{
+ void operator()(__shared_count* p) {p->__release_shared();}
+};
+
+template <class _R>
+future<_R>::~future()
+{
+ if (__state_)
+ __state_->__release_shared();
+}
+
+template <class _R>
+_R
+future<_R>::get()
+{
+ unique_ptr<__shared_count, __release_shared_count> __(__state_);
+ __assoc_state<_R>* __s = __state_;
+ __state_ = nullptr;
+ return __s->move();
+}
+
+template <class _R>
+class _LIBCPP_VISIBLE future<_R&>
+{
+ __assoc_state<_R&>* __state_;
+
+ explicit future(__assoc_state<_R&>* __state);
+
+ template <class> friend class promise;
+ template <class> friend class shared_future;
+ template <class> friend class atomic_future;
+
+ template <class _R1, class _F>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ friend future<_R1> __make_deferred_assoc_state(_F&& __f);
+#else
+ friend future<_R1> __make_deferred_assoc_state(_F __f);
+#endif
+
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ future() : __state_(nullptr) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ _LIBCPP_INLINE_VISIBILITY
+ future(future&& __rhs)
+ : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+ future(const future&) = delete;
+ future& operator=(const future&) = delete;
+ _LIBCPP_INLINE_VISIBILITY
+ future& operator=(future&& __rhs)
+ {
+ future(std::move(__rhs)).swap(*this);
+ return *this;
+ }
+#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+ future(const future&);
+ future& operator=(const future&);
+public:
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ ~future();
+ shared_future<_R&> share();
+
+ // retrieving the value
+ _R& get();
+
+ _LIBCPP_INLINE_VISIBILITY
+ void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
+
+ // functions to check state
+ _LIBCPP_INLINE_VISIBILITY
+ bool valid() const {return __state_ != nullptr;}
+
+ _LIBCPP_INLINE_VISIBILITY
+ void wait() const {__state_->wait();}
+ template <class _Rep, class _Period>
+ _LIBCPP_INLINE_VISIBILITY
+ future_status
+ wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+ {return __state_->wait_for(__rel_time);}
+ template <class _Clock, class _Duration>
+ _LIBCPP_INLINE_VISIBILITY
+ future_status
+ wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+ {return __state_->wait_until(__abs_time);}
+};
+
+template <class _R>
+future<_R&>::future(__assoc_state<_R&>* __state)
+ : __state_(__state)
+{
+ if (__state_->__has_future_attached())
+ throw future_error(make_error_code(future_errc::future_already_retrieved));
+ __state_->__add_shared();
+ __state_->__set_future_attached();
+}
+
+template <class _R>
+future<_R&>::~future()
+{
+ if (__state_)
+ __state_->__release_shared();
+}
+
+template <class _R>
+_R&
+future<_R&>::get()
+{
+ unique_ptr<__shared_count, __release_shared_count> __(__state_);
+ __assoc_state<_R&>* __s = __state_;
+ __state_ = nullptr;
+ return __s->copy();
+}
+
+template <>
+class _LIBCPP_VISIBLE future<void>
+{
+ __assoc_sub_state* __state_;
+
+ explicit future(__assoc_sub_state* __state);
+
+ template <class> friend class promise;
+ template <class> friend class shared_future;
+ template <class> friend class atomic_future;
+
+ template <class _R1, class _F>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ friend future<_R1> __make_deferred_assoc_state(_F&& __f);
+#else
+ friend future<_R1> __make_deferred_assoc_state(_F __f);
+#endif
+
+public:
+ _LIBCPP_INLINE_VISIBILITY
+ future() : __state_(nullptr) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ _LIBCPP_INLINE_VISIBILITY
+ future(future&& __rhs)
+ : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+ future(const future&) = delete;
+ future& operator=(const future&) = delete;
+ _LIBCPP_INLINE_VISIBILITY
+ future& operator=(future&& __rhs)
+ {
+ future(std::move(__rhs)).swap(*this);
+ return *this;
+ }
+#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+ future(const future&);
+ future& operator=(const future&);
+public:
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ ~future();
+ shared_future<void> share();
+
+ // retrieving the value
+ void get();
+
+ _LIBCPP_INLINE_VISIBILITY
+ void swap(future& __rhs) {_STD::swap(__state_, __rhs.__state_);}
+
+ // functions to check state
+ _LIBCPP_INLINE_VISIBILITY
+ bool valid() const {return __state_ != nullptr;}
+
+ _LIBCPP_INLINE_VISIBILITY
+ void wait() const {__state_->wait();}
+ template <class _Rep, class _Period>
+ _LIBCPP_INLINE_VISIBILITY
+ future_status
+ wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+ {return __state_->wait_for(__rel_time);}
+ template <class _Clock, class _Duration>
+ _LIBCPP_INLINE_VISIBILITY
+ future_status
+ wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+ {return __state_->wait_until(__abs_time);}
+};
+
+template <class _R>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(future<_R>& __x, future<_R>& __y)
+{
+ __x.swap(__y);
+}
+
+// promise<R>
+
+template <class> class packaged_task;
+
+template <class _R>
+class _LIBCPP_VISIBLE promise
+{
+ __assoc_state<_R>* __state_;
+
+ _LIBCPP_INLINE_VISIBILITY
+ explicit promise(nullptr_t) : __state_(nullptr) {}
+
+ template <class> friend class packaged_task;
+public:
+ promise();
+ template <class _Alloc>
+ promise(allocator_arg_t, const _Alloc& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ _LIBCPP_INLINE_VISIBILITY
+ promise(promise&& __rhs)
+ : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+ promise(const promise& __rhs) = delete;
+#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+ promise(const promise& __rhs);
+public:
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ ~promise();
+
+ // assignment
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ _LIBCPP_INLINE_VISIBILITY
+ promise& operator=(promise&& __rhs)
+ {
+ promise(std::move(__rhs)).swap(*this);
+ return *this;
+ }
+ promise& operator=(const promise& __rhs) = delete;
+#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+ promise& operator=(const promise& __rhs);
+public:
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ _LIBCPP_INLINE_VISIBILITY
+ void swap(promise& __rhs) {_STD::swap(__state_, __rhs.__state_);}
+
+ // retrieving the result
+ future<_R> get_future();
+
+ // setting the result
+ void set_value(const _R& __r);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void set_value(_R&& __r);
+#endif
+ void set_exception(exception_ptr __p);
+
+ // setting the result with deferred notification
+ void set_value_at_thread_ex