1#ifndef MSTL_CORE_ASYNC_FUTURE_HPP__
2#define MSTL_CORE_ASYNC_FUTURE_HPP__
43template <typename Res>
46template <typename Res>
49template <typename Sign>
52template <typename Res>
94 return static_cast<launch>(
static_cast<int>(left) &
static_cast<int>(right));
97 return static_cast<launch>(
static_cast<int>(left) |
static_cast<int>(right));
100 return static_cast<launch>(
static_cast<int>(left) ^
static_cast<int>(right));
102constexpr launch operator ~(
const launch value)
noexcept {
103 return static_cast<launch>(~static_cast<int>(value));
107 return left = left & right;
110 return left = left | right;
113 return left = left ^ right;
123template <
typename Func,
typename... Args>
126template <
typename Func,
typename... Args>
130template <
typename Func,
typename... Args>
138constexpr const char* future_errc_cstr(
const future_errc code) {
141 return "future_already_retrieved";
144 return "promise_already_satisfied";
150 return "broken_promise";
164struct __future_base {
172 exception_ptr error_ptr{
nullptr};
175 result_base() noexcept {}
176 virtual ~result_base() =
default;
179 result_base(
const result_base&) =
delete;
180 result_base& operator =(
const result_base&) =
delete;
193 void operator ()(result_base* result)
const {
199 template <
typename Res>
200 using Ptr = unique_ptr<Res, result_base::Deleter>;
209 template <
typename Res>
210 struct basic_result : result_base {
212 aligned_buffer<Res> storage;
221 using result_type = Res;
226 basic_result() noexcept : initialized() {}
232 ~basic_result()
override {
242 Res& value() noexcept {
243 return *storage.
ptr();
250 void set(Res&& result) {
264 template <
typename Res,
typename Alloc>
265 struct allocated_result final : basic_result<Res>, Alloc {
266 using allocator_type =
_INNER __allocator_traits_base::alloc_rebind_t<Alloc, allocated_result>;
272 explicit allocated_result(
const Alloc& alloc)
273 : basic_result<Res>(), Alloc(alloc) {}
280 allocator_type alloc(*
this);
281 allocated_ptr<allocator_type> guard_ptr{ alloc,
this };
282 this->~AllocatedResult();
293 template <
typename Res,
typename Alloc>
294 static Ptr<allocated_result<Res, Alloc>>
295 allocate_result(
const Alloc& alloc) {
296 using result_type = allocated_result<Res, Alloc>;
297 typename result_type::allocator_type alloc2(alloc);
299 result_type* ptr =
new(
static_cast<void*
>(guard.get())) result_type{alloc};
301 return Ptr<result_type>(ptr);
310 template <
typename Res,
typename T>
311 static Ptr<basic_result<Res>>
313 return Ptr<basic_result<Res>>(
new basic_result<Res>);
324 using PtrType = Ptr<result_base>;
334 atomic_futex<> status;
335 atomic_flag retrieved;
342 state_base() noexcept
343 : status(status::not_ready), retrieved(false) {
347 state_base(
const state_base&) =
delete;
348 state_base& operator =(
const state_base&) =
delete;
349 virtual ~state_base() =
default;
356 result_base&
wait() {
369 template <
typename Rep,
typename Period>
375 if (is_deferred_future()) {
394 template <
typename Clock,
typename Dur>
395 future_status wait_until(
const time_point<Clock, Dur>& absolute_time) {
401 if (is_deferred_future()) {
419 template <
typename Callable>
420 void set_result(Callable&& result_func,
const bool ignore_failure =
false) {
421 bool did_set =
false;
426 }
else if (!ignore_failure) {
439 template <
typename Callable>
440 void set_delayed_result(Callable&& result_func, weak_ptr<state_base> self) {
441 bool did_set =
false;
458 void break_promise(PtrType result) {
459 if (
static_cast<bool>(result)) {
462 result_ptr.swap(result);
471 void set_retrieved_flag() {
484 template <
typename Res,
typename Arg>
490 template <
typename Res,
typename Arg>
491 struct setter<Res, Arg&> {
492 static_assert(is_same_v<Res, Arg&> || is_same_v<const Res, Arg>,
"Invalid specialisation");
494 typename promise<Res>::PtrType operator ()()
const {
495 promise_ptr->storage->set(*arg_ptr);
498 promise<Res>* promise_ptr;
505 template <
typename Res>
506 struct setter<Res, Res&&> {
507 typename promise<Res>::PtrType operator ()()
const {
508 promise_ptr->storage->set(
_MSTL move(*arg_ptr));
511 promise<Res>* promise_ptr;
518 template <
typename Res>
519 struct setter<Res, void> {
520 static_assert(is_void_v<Res>,
"Only used for promise<void>");
525 promise<Res>* promise_ptr;
528 struct exception_ptr_tag {};
533 template <
typename Res>
534 struct setter<Res, exception_ptr_tag> {
536 promise_ptr->storage->error_ptr = *exp_ptr;
539 promise<Res>* promise_ptr;
540 exception_ptr* exp_ptr;
546 template <
typename Res,
typename Arg>
547 MSTL_ALWAYS_INLINE
static setter<Res, Arg&&>
548 create_setter(promise<Res>* promise_ptr, Arg&& arg)
noexcept {
555 template <
typename Res>
556 MSTL_ALWAYS_INLINE
static setter<Res, exception_ptr_tag>
557 create_setter(exception_ptr& exception, promise<Res>* promise_ptr)
noexcept {
558 return setter<Res, exception_ptr_tag>{ promise_ptr, &exception };
564 template <
typename Res>
565 MSTL_ALWAYS_INLINE
static setter<Res, void>
566 create_setter(promise<Res>* promise_ptr)
noexcept {
567 return setter<Res, void>{ promise_ptr };
576 template <
typename T>
577 static void check(
const shared_ptr<T>& ptr) {
578 if (!
static_cast<bool>(ptr)) {
589 void do_set(function<PtrType()>* func,
bool* did_set) {
590 PtrType result = (*func)();
592 result_ptr.swap(result);
599 virtual void complete_async() {}
605 virtual bool is_deferred_future()
const {
614 struct make_ready final : at_thread_exit_elt {
615 weak_ptr<state_base> shared_state;
621 static void run(
void* ptr) {
622 const auto self =
static_cast<make_ready*
>(ptr);
623 const auto state = self->shared_state.
lock();
644 template <
typename Ptr>
645 struct get_result_type {
646 using type =
typename Ptr::element_type::result_type;
649 template <
typename Ptr>
650 using result_res_t =
typename get_result_type<Ptr>::type;
653 class async_state_common;
655 template <typename BoundFunc, typename Res = decltype(_MSTL declval<BoundFunc&>()())>
656 class deferred_state;
658 template <typename BoundFunc, typename Res = decltype(_MSTL declval<BoundFunc&>()())>
659 class async_state_impl;
661 template <
typename Sign>
662 class task_state_base;
664 template <
typename Func,
typename Alloc,
typename Sign>
667 template <
typename ResPtrT,
typename Func,
typename ResT = result_res_t<ResPtrT>>
673 template <
typename ResPtr,
typename BoundFunc>
674 static task_setter<ResPtr, BoundFunc>
675 create_task_setter(ResPtr& ptr, BoundFunc& call) {
684template <
typename Res>
685struct __future_base::basic_result<Res&> : __future_base::result_base {
689 void destroy()
override {
delete this; }
692 using result_type = Res&;
697 basic_result() noexcept : value_ptr() {}
703 void set(Res& result)
noexcept {
711 MSTL_NODISCARD Res&
get() noexcept {
720struct __future_base::basic_result<void> : __future_base::result_base {
721 using result_type = void;
724 void destroy()
override {
delete this; }
734template <
typename Res>
735class __basic_future :
public __future_base {
737 using state_type = shared_ptr<state_base>;
738 using result_type = __future_base::basic_result<Res>&;
741 state_type state_ptr;
744 __basic_future(
const __basic_future&) =
delete;
745 __basic_future& operator =(
const __basic_future&) =
delete;
751 bool valid() const noexcept {
752 return static_cast<bool>(state_ptr);
760 state_base::check(state_ptr);
772 template <
typename Rep,
typename Period>
774 state_base::check(state_ptr);
786 template <
typename Clock,
typename Dur>
787 future_status wait_until(
const time_point<Clock, Dur>& absolute_time)
const {
788 state_base::check(state_ptr);
789 return state_ptr->wait_until(absolute_time);
797 result_type get_result()
const {
798 state_base::check(state_ptr);
799 result_base& result = state_ptr->wait();
800 if (result.error_ptr !=
nullptr) {
803 return static_cast<result_type
>(result);
810 void swap(__basic_future& other)
noexcept {
811 state_ptr.swap(other.state_ptr);
818 explicit __basic_future(
const state_type& state)
820 state_base::check(state_ptr);
821 state_ptr->set_retrieved_flag();
824 explicit __basic_future(
const shared_future<Res>&)
noexcept;
825 explicit __basic_future(shared_future<Res>&&) noexcept;
826 explicit __basic_future(future<Res>&&) noexcept;
831 constexpr __basic_future() noexcept {}
839 __basic_future& future_ref;
845 explicit reset(__basic_future& future) noexcept
846 : future_ref(future) {}
852 future_ref.state_ptr.reset();
861template <
typename Res,
typename Arg>
864template <
typename ResPtr,
typename Func,
typename Res>
876template <
typename Res>
877class future :
public _INNER __basic_future<Res> {
878 static_assert(!is_array_v<Res>,
"result type must not be an array");
879 static_assert(!is_function_v<Res>,
"result type must not be a function");
880 static_assert(is_destructible_v<Res>,
"result type must be destructible");
884 template <
typename Sign>
885 friend class packaged_task;
887 template <
typename Function,
typename... Args>
891 using base_type =
_INNER __basic_future<Res>;
892 using state_type =
typename base_type::state_type;
897 explicit future(
const state_type& state) : base_type(state) {}
921 future& operator =(future&& other)
noexcept {
932 typename base_type::reset reset_(*
this);
933 return _MSTL move(this->get_result().value());
947template <typename Res>
948class future<Res&> : public
_INNER __basic_future<Res&> {
951 template <
typename Sign>
952 friend class packaged_task;
954 template <
typename Function,
typename... Args>
958 typedef _INNER __basic_future<Res&> base_type;
959 typedef typename base_type::state_type state_type;
961 explicit future(
const state_type& state) : base_type(state) {}
964 constexpr future() noexcept : base_type() {}
967 future(
const future&) =
delete;
968 future& operator =(
const future&) =
delete;
970 future& operator =(future&& other)
noexcept {
981 typename base_type::reset reset_(*
this);
982 return this->get_result().get();
992class future<
void> : public
_INNER __basic_future<
void> {
995 template <
typename>
friend class packaged_task;
997 template <
typename Function,
typename... Args>
1001 using base_type =
_INNER __basic_future<void>;
1002 using state_type = base_type::state_type;
1004 explicit future(
const state_type& state) : base_type(state) {}
1007 constexpr future()
noexcept {}
1010 future(
const future&) =
delete;
1011 future& operator =(
const future&) =
delete;
1013 future& operator =(future&& other)
noexcept {
1023 base_type::reset reset(*
this);
1024 MSTL_IGNORE this->get_result();
1037template <typename Res>
1038class shared_future : public
_INNER __basic_future<Res> {
1039 static_assert(!is_array_v<Res>,
"result type must not be an array");
1040 static_assert(!is_function_v<Res>,
"result type must not be a function");
1041 static_assert(is_destructible_v<Res>,
"result type must be destructible");
1043 using base_type =
_INNER __basic_future<Res>;
1046 constexpr shared_future() noexcept : base_type() {}
1047 shared_future(
const shared_future& other) noexcept : base_type(other) {}
1049 shared_future(shared_future&& other) noexcept : base_type(
_MSTL move(other)) {}
1051 shared_future& operator =(
const shared_future& other)
noexcept {
1052 shared_future(other).swap(*
this);
1056 shared_future& operator =(shared_future&& other)
noexcept {
1057 shared_future(
_MSTL move(other)).swap(*
this);
1067 return this->get_result().value();
1075template <
typename Res>
1076class shared_future<Res&> :
public _INNER __basic_future<Res&> {
1077 using base_type =
_INNER __basic_future<Res&>;
1080 constexpr shared_future() noexcept : base_type() {}
1081 shared_future(
const shared_future& other) : base_type(other) {}
1083 shared_future(shared_future&& other) noexcept : base_type(
_MSTL move(other)) {}
1085 shared_future& operator =(
const shared_future& other) {
1086 shared_future(other).swap(*
this);
1090 shared_future& operator =(shared_future&& other)
noexcept {
1091 shared_future(
_MSTL move(other)).swap(*
this);
1100 return this->get_result().get();
1108class shared_future<void> :
public _INNER __basic_future<void> {
1109 using base_type =
_INNER __basic_future<void>;
1112 constexpr shared_future()
noexcept {}
1113 shared_future(
const shared_future& other) : base_type(other) {}
1115 shared_future(shared_future&& other) noexcept : base_type(
_MSTL move(other)) {}
1117 shared_future& operator =(
const shared_future& other) {
1118 shared_future(other).swap(*
this);
1122 shared_future& operator =(shared_future&& other)
noexcept {
1123 shared_future(
_MSTL move(other)).swap(*
this);
1131 MSTL_IGNORE this->get_result();
1137template <
typename Res>
1138_INNER __basic_future<Res>::__basic_future(
const shared_future<Res>& other) noexcept
1139: state_ptr(other.state_ptr) {}
1141template <
typename Res>
1142_INNER __basic_future<Res>::__basic_future(shared_future<Res>&& other) noexcept
1143: state_ptr(
_MSTL move(other.state_ptr)) {}
1145template <
typename Res>
1146_INNER __basic_future<Res>::__basic_future(future<Res>&& other) noexcept
1147: state_ptr(
_MSTL move(other.state_ptr)) {}
1150template <
typename Result>
1152 return shared_future<Result>(
_MSTL move(*
this));
1155template <
typename Res>
1157 return shared_future<Res&>(
_MSTL move(*
this));
1161 return shared_future<void>(
_MSTL move(*
this));
1172template <
typename T>
1189template <
typename T>
1199template <
typename T>
1213template <
typename T>
MSTL_ALWAYS_INLINE bool load_when_equal_for(const uint32_t value, const memory_order mo, const duration< Rep, Period > &rtime)
在指定时间内等待值等于指定值
MSTL_ALWAYS_INLINE void store_notify_all(const uint32_t value, const memory_order mo)
存储新值并通知所有等待线程
MSTL_ALWAYS_INLINE void load_when_equal(const uint32_t value, const memory_order mo)
等待直到值等于指定值
MSTL_ALWAYS_INLINE bool load_when_equal_until(const uint32_t value, const memory_order mo, const time_point< Clock, Dur > &atime)
在指定时间点前等待值等于指定值(通用时钟)
MSTL_NODISCARD MSTL_ALWAYS_INLINE uint32_t load(const memory_order mo) const
原子加载数据
constexpr future() noexcept
默认构造函数
future(future &&other) noexcept
移动构造函数
shared_future< Res > share() noexcept
转换为共享future
_INNER __future_base::Ptr< result_type > ptr_type
结果指针类型
const Res & get() const
获取常量引用结果
MSTL_CONSTEXPR20 pointer release() noexcept
释放所有权
MSTL_NODISCARD shared_ptr< T > lock() const noexcept
尝试获取共享智能指针
allocated_ptr< Alloc > allocate_guarded(Alloc &alloc)
分配内存并创建allocated_ptr
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
MSTL_NODISCARD future< async_result_t< Func, Args... > > async(launch policy, Func &&function, Args &&... args)
异步执行函数(指定策略)
invoke_result_t< decay_t< Func >, decay_t< Args >... > async_result_t
异步调用结果类型推导
typename future_result< T >::type future_result_t
future结果类型别名
MSTL_ALWAYS_INLINE enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
@ future_already_retrieved
future已经被获取
@ promise_already_satisfied
promise已经被满足
void call_once(once_flag &flag, Callable &&func, Args &&... args)
单次调用函数
MSTL_INLINE17 constexpr bool is_clock_v
is_clock的便捷变量模板
milliseconds MSTL_API relative_time(int64_t sec, int64_t nsec, bool is_monotonic=false)
将绝对时间戳转换为相对延迟毫秒数
unsigned int uint32_t
32位无符号整数类型
#define MSTL_ERROR_BUILD_FINAL_CLASS(THIS, BASE, INFO)
构建最终异常类宏
exception_ptr make_exception_ptr(Ex ex) noexcept
创建异常指针
void MSTL_API rethrow_exception(const exception_ptr &p)
重新抛出异常
MSTL_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
typename _INNER __invoke_result_aux< F, Args... >::type invoke_result_t
invoke_result的便捷别名
standard_allocator< T > allocator
标准分配器别名
MSTL_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
MSTL_INLINE17 constexpr none_t none
默认空表示
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
void swap()=delete
删除无参数的swap重载
void MSTL_API at_thread_exit_register(at_thread_exit_elt *elt, void(*callback)(void *)) noexcept
注册线程退出回调
typename decay< T >::type decay_t
decay的便捷别名
bool_constant< true > true_type
表示true的类型
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
void * addr() noexcept
获取缓冲区的原始地址
T * ptr() noexcept
获取缓冲区的类型化指针
MSTL_ALWAYS_INLINE void clear(const memory_order mo=memory_order_seq_cst) noexcept
清除标志
MSTL_ALWAYS_INLINE bool test_and_set(const memory_order mo=memory_order_seq_cst) noexcept
测试并设置标志
static constexpr duration zero() noexcept
获取零持续时间
exception(const char *info=static_type, const char *type=static_type, const int code=0)
构造函数