1#ifndef NEFORCE_CORE_ASYNC_FUTURE_HPP__
2#define NEFORCE_CORE_ASYNC_FUTURE_HPP__
21NEFORCE_BEGIN_NAMESPACE__
34 explicit future_exception(
const char* info =
"Future Operation Failed.") noexcept :
37 explicit future_exception(
const exception& e) :
40 ~future_exception()
override =
default;
42 NEFORCE_NODISCARD
const char*
type() const noexcept
override {
return "future_exception"; }
60template <
typename Res>
63template <
typename Res>
66template <
typename Sign>
69template <
typename Res>
110constexpr launch operator&(
const launch left,
const launch right)
noexcept {
111 return static_cast<launch
>(
static_cast<int>(left) &
static_cast<int>(right));
113constexpr launch operator|(
const launch left,
const launch right)
noexcept {
114 return static_cast<launch>(
static_cast<int>(
left) |
static_cast<int>(
right));
116constexpr launch operator^(
const launch left,
const launch right)
noexcept {
117 return static_cast<launch>(
static_cast<int>(
left) ^
static_cast<int>(
right));
119constexpr launch operator~(
const launch value)
noexcept {
return static_cast<launch>(~static_cast<int>(value)); }
121constexpr launch& operator&=(launch& left,
const launch right)
noexcept {
return left =
left &
right; }
122constexpr launch& operator|=(launch& left,
const launch right)
noexcept {
return left =
left |
right; }
123constexpr launch& operator^=(launch& left,
const launch right)
noexcept {
return left =
left ^
right; }
132template <
typename Func,
typename... Args>
135template <
typename Func,
typename... Args>
138template <
typename Func,
typename... Args>
145constexpr const char* future_errc_cstr(
const future_errc code) {
148 return "future_already_retrieved";
150 case future_errc::promise_already_satisfied: {
151 return "promise_already_satisfied";
153 case future_errc::no_state: {
156 case future_errc::broken_promise: {
157 return "broken_promise";
171struct __future_base {
179 exception_ptr error_ptr{
nullptr};
182 result_base() noexcept = default;
185 result_base(const result_base&) = delete;
186 result_base& operator=(const result_base&) = delete;
188 virtual ~result_base() = default;
194 virtual
void destroy() = 0;
201 void operator()(result_base* result)
const { result->destroy(); }
205 template <
typename Res>
206 using Ptr = unique_ptr<Res, result_base::Deleter>;
215 template <
typename Res>
216 struct basic_result : result_base {
218 aligned_buffer<Res> storage;
219 bool initialized =
false;
222 void destroy()
override {
delete this; }
225 using result_type = Res;
230 basic_result() noexcept = default;
236 ~basic_result()
override {
246 Res& value() noexcept {
return *storage.ptr(); }
252 void set(Res&& result) {
253 new (storage.addr()) Res(_NEFORCE forward<Res>(result));
266 template <
typename Res,
typename Alloc>
267 struct allocated_result final : basic_result<Res>, Alloc {
268 using allocator_type = inner::__allocator_traits_base::alloc_rebind_t<Alloc, allocated_result>;
274 explicit allocated_result(
const Alloc& alloc) :
283 allocator_type alloc(*
this);
284 allocated_ptr<allocator_type> guard_ptr{alloc,
this};
285 this->~AllocatedResult();
296 template <
typename Res,
typename Alloc>
297 static Ptr<allocated_result<Res, Alloc>> allocate_result(
const Alloc& alloc) {
298 using result_type = allocated_result<Res, Alloc>;
299 typename result_type::allocator_type alloc2(alloc);
301 auto* ptr =
new (
static_cast<void*
>(guard.get())) result_type{alloc};
303 return Ptr<result_type>(ptr);
312 template <
typename Res,
typename T>
313 static Ptr<basic_result<Res>> allocate_result(
const _NEFORCE allocator<T>& ) {
314 return Ptr<basic_result<Res>>(
new basic_result<Res>);
325 using PtrType = Ptr<result_base>;
335 atomic_futex<> status{status::not_ready};
336 atomic_flag retrieved;
343 state_base() noexcept { retrieved.clear(); }
345 state_base(
const state_base&) =
delete;
346 state_base& operator=(
const state_base&) =
delete;
347 virtual ~state_base() =
default;
354 result_base&
wait() {
356 status.load_when_equal(status::ready, memory_order_acquire);
367 template <
typename Rep,
typename Period>
368 future_status wait_for(
const duration<Rep, Period>& relative_time) {
369 if (status.load(memory_order_acquire) == status::ready) {
370 return future_status::ready;
373 if (is_deferred_future()) {
374 return future_status::deferred;
378 status.load_when_equal_for(status::ready, memory_order_acquire, relative_time)) {
380 return future_status::ready;
382 return future_status::timeout;
392 template <
typename Clock,
typename Dur>
393 future_status wait_until(
const time_point<Clock, Dur>& absolute_time) {
394 static_assert(is_clock_v<Clock>,
"Clock type must be clock_t");
395 if (status.load(memory_order_acquire) == status::ready) {
396 return future_status::ready;
399 if (is_deferred_future()) {
400 return future_status::deferred;
403 if (status.load_when_equal_until(status::ready, memory_order_acquire, absolute_time)) {
405 return future_status::ready;
407 return future_status::timeout;
417 template <
typename Callable>
418 void set_result(Callable&& result_func,
const bool ignore_failure =
false) {
419 bool did_set =
false;
420 function<PtrType()> func = _NEFORCE forward<Callable>(result_func);
423 status.store_notify_all(status::ready, memory_order_release);
424 }
else if (!ignore_failure) {
425 NEFORCE_THROW_EXCEPTION(future_exception(future_errc_cstr(future_errc::promise_already_satisfied)));
437 template <
typename Callable>
438 void set_delayed_result(Callable&& result_func, weak_ptr<state_base> self) {
439 bool did_set =
false;
440 unique_ptr<make_ready> mr = make_unique<make_ready>();
441 function<PtrType()> func = _NEFORCE forward<Callable>(result_func);
444 NEFORCE_THROW_EXCEPTION(future_exception(future_errc_cstr(future_errc::promise_already_satisfied)));
446 mr->shared_state = _NEFORCE
move(self);
456 void break_promise(PtrType result) {
457 if (
static_cast<bool>(result)) {
458 result->error_ptr =
make_exception_ptr(future_exception(future_errc_cstr(future_errc::broken_promise)));
459 result_ptr.swap(result);
460 status.store_notify_all(status::ready, memory_order_release);
468 void set_retrieved_flag() {
469 if (retrieved.test_and_set(memory_order_acquire)) {
470 NEFORCE_THROW_EXCEPTION(future_exception(future_errc_cstr(future_errc::future_already_retrieved)));
481 template <
typename Res,
typename Arg>
487 template <
typename Res,
typename Arg>
488 struct setter<Res, Arg&> {
489 static_assert(is_same_v<Res, Arg&> || is_same_v<const Res, Arg>,
"Invalid specialisation");
491 typename promise<Res>::ptr_type operator()()
const {
492 promise_ptr->storage->set(*arg_ptr);
493 return _NEFORCE
move(promise_ptr->storage);
495 promise<Res>* promise_ptr;
502 template <
typename Res>
503 struct setter<Res, Res&&> {
504 typename promise<Res>::ptr_type operator()()
const {
505 promise_ptr->storage->set(_NEFORCE
move(*arg_ptr));
506 return _NEFORCE
move(promise_ptr->storage);
508 promise<Res>* promise_ptr;
515 template <
typename Res>
516 struct setter<Res, void> {
517 static_assert(is_void_v<Res>,
"Only used for promise<void>");
519 typename promise<Res>::ptr_type operator()()
const {
return _NEFORCE
move(promise_ptr->storage); }
520 promise<Res>* promise_ptr;
523 struct exception_ptr_tag {};
528 template <
typename Res>
529 struct setter<Res, exception_ptr_tag> {
530 typename promise<Res>::ptr_type operator()()
const {
531 promise_ptr->storage->error_ptr = *exp_ptr;
532 return _NEFORCE
move(promise_ptr->storage);
534 promise<Res>* promise_ptr;
535 exception_ptr* exp_ptr;
541 template <
typename Res,
typename Arg>
542 NEFORCE_ALWAYS_INLINE
static setter<Res, Arg&&> create_setter(promise<Res>* promise_ptr, Arg&& arg)
noexcept {
543 return setter<Res, Arg&&>{promise_ptr, _NEFORCE
addressof(arg)};
549 template <
typename Res>
550 NEFORCE_ALWAYS_INLINE
static setter<Res, exception_ptr_tag> create_setter(exception_ptr& exception,
551 promise<Res>* promise_ptr)
noexcept {
552 return setter<Res, exception_ptr_tag>{promise_ptr, &exception};
558 template <
typename Res>
559 NEFORCE_ALWAYS_INLINE
static setter<Res, void> create_setter(promise<Res>* promise_ptr)
noexcept {
560 return setter<Res, void>{promise_ptr};
569 template <
typename T>
570 static void check(
const shared_ptr<T>& ptr) {
571 if (!
static_cast<bool>(ptr)) {
572 NEFORCE_THROW_EXCEPTION(future_exception(future_errc_cstr(future_errc::no_state)));
582 void do_set(function<PtrType()>* func,
bool* did_set) {
583 PtrType result = (*func)();
585 result_ptr.swap(result);
592 virtual void complete_async() {}
598 NEFORCE_NODISCARD
virtual bool is_deferred_future()
const {
return false; }
605 struct make_ready final : thread_exit_elt {
606 weak_ptr<state_base> shared_state;
612 static void run(
void* ptr)
noexcept {
613 auto*
const self =
static_cast<make_ready*
>(ptr);
614 const auto state = self->shared_state.lock();
616 state->status.store_notify_all(status::ready, memory_order_release);
633 template <
typename Ptr>
634 struct get_result_type {
635 using type =
typename Ptr::element_type::result_type;
638 template <
typename Ptr>
639 using result_res_t =
typename get_result_type<Ptr>::type;
642 class async_state_common;
644 template <typename BoundFunc, typename Res = decltype(_NEFORCE declval<BoundFunc&>()())>
645 class deferred_state;
647 template <typename BoundFunc, typename Res = decltype(_NEFORCE declval<BoundFunc&>()())>
648 class async_state_impl;
650 template <
typename Sign>
651 class task_state_base;
653 template <
typename Func,
typename Alloc,
typename Sign>
656 template <
typename ResPtrT,
typename Func,
typename ResT = result_res_t<ResPtrT>>
662 template <
typename ResPtr,
typename BoundFunc>
663 static task_setter<ResPtr, BoundFunc> create_task_setter(ResPtr& ptr, BoundFunc& call) {
672template <
typename Res>
673struct __future_base::basic_result<Res&> : __future_base::result_base {
677 void destroy()
override {
delete this; }
680 using result_type = Res&;
685 basic_result() noexcept :
692 void set(Res& result)
noexcept { value_ptr = _NEFORCE
addressof(result); }
698 NEFORCE_NODISCARD Res&
get() noexcept {
return *value_ptr; }
705struct __future_base::basic_result<void> : __future_base::result_base {
706 using result_type = void;
709 void destroy()
override {
delete this; }
719template <
typename Res>
720class __basic_future :
public __future_base {
722 using state_type = shared_ptr<state_base>;
723 using result_type = __future_base::basic_result<Res>&;
726 state_type state_ptr;
729 __basic_future(
const __basic_future&) =
delete;
730 __basic_future& operator=(
const __basic_future&) =
delete;
736 NEFORCE_NODISCARD
bool valid() const noexcept {
return static_cast<bool>(state_ptr); }
743 state_base::check(state_ptr);
755 template <
typename Rep,
typename Period>
756 future_status wait_for(
const duration<Rep, Period>& relative_time)
const {
757 state_base::check(state_ptr);
758 return state_ptr->wait_for(relative_time);
769 template <
typename Clock,
typename Dur>
770 future_status wait_until(
const time_point<Clock, Dur>& absolute_time)
const {
771 state_base::check(state_ptr);
772 return state_ptr->wait_until(absolute_time);
780 NEFORCE_NODISCARD result_type get_result()
const {
781 state_base::check(state_ptr);
782 result_base& result = state_ptr->wait();
783 if (result.error_ptr !=
nullptr) {
786 return static_cast<result_type
>(result);
793 void swap(__basic_future& other)
noexcept { state_ptr.swap(other.state_ptr); }
799 explicit __basic_future(state_type state) :
800 state_ptr(
move(state)) {
801 state_base::check(state_ptr);
802 state_ptr->set_retrieved_flag();
805 explicit __basic_future(
const shared_future<Res>& other)
noexcept;
806 explicit __basic_future(shared_future<Res>&& other)
noexcept;
807 explicit __basic_future(future<Res>&& other)
noexcept;
812 constexpr __basic_future() noexcept = default;
820 __basic_future& future_ref;
826 explicit reset(__basic_future& future) noexcept :
827 future_ref(future) {}
832 ~reset() { future_ref.state_ptr.reset(); }
840template <
typename Res,
typename Arg>
841struct is_location_invariant<inner::__future_base::state_base::setter<Res, Arg>> :
true_type {};
843template <
typename ResPtr,
typename Func,
typename Res>
844struct is_location_invariant<inner::__future_base::task_setter<ResPtr, Func, Res>> :
true_type {};
855template <
typename Res>
856class future :
public inner::__basic_future<Res> {
863 template <
typename Sign>
864 friend class packaged_task;
866 template <
typename Function,
typename... Args>
869 using base_type = inner::__basic_future<Res>;
870 using state_type =
typename base_type::state_type;
875 explicit future(
const state_type& state) :
890 base_type(_NEFORCE
move(other)) {}
901 future(_NEFORCE
move(other)).swap(*
this);
911 typename base_type::reset reset_(*
this);
912 return _NEFORCE
move(this->get_result().value());
926template <typename Res>
927class future<Res&> : public inner::__basic_future<Res&> {
930 template <
typename Sign>
931 friend class packaged_task;
933 template <
typename Function,
typename... Args>
936 using base_type = inner::__basic_future<Res&>;
937 using state_type =
typename base_type::state_type;
939 explicit future(
const state_type& state) :
943 constexpr future() noexcept :
945 future(future&& other) noexcept :
946 base_type(_NEFORCE
move(other)) {}
948 future(
const future&) =
delete;
949 future& operator=(
const future&) =
delete;
951 future& operator=(future&& other)
noexcept {
952 future(_NEFORCE
move(other)).swap(*
this);
962 typename base_type::reset reset_(*
this);
963 return this->get_result().get();
973class future<
void> : public inner::__basic_future<
void> {
977 friend class packaged_task;
979 template <
typename Function,
typename... Args>
982 using base_type = inner::__basic_future<void>;
984 using state_type = base_type::state_type;
986 explicit future(state_type state) :
987 base_type(
move(state)) {}
990 future()
noexcept =
default;
992 future(future&& other) noexcept :
993 base_type(_NEFORCE
move(other)) {}
995 future(
const future&) =
delete;
996 future& operator=(
const future&) =
delete;
998 future& operator=(future&& other)
noexcept {
999 future(_NEFORCE
move(other)).swap(*
this);
1008 base_type::reset
reset(*
this);
1009 ignore = this->get_result();
1022template <typename Res>
1023class shared_future : public inner::__basic_future<Res> {
1028 using base_type = inner::__basic_future<Res>;
1031 constexpr shared_future() noexcept :
1033 shared_future(
const shared_future& other) noexcept :
1036 base_type(_NEFORCE
move(other)) {}
1037 shared_future(shared_future&& other) noexcept :
1038 base_type(_NEFORCE
move(other)) {}
1040 shared_future& operator=(
const shared_future& other)
noexcept {
1041 shared_future(other).swap(*
this);
1045 shared_future& operator=(shared_future&& other)
noexcept {
1046 shared_future(_NEFORCE
move(other)).swap(*
this);
1055 const Res&
get()
const {
return this->get_result().value(); }
1062template <
typename Res>
1063class shared_future<Res&> :
public inner::__basic_future<Res&> {
1064 using base_type = inner::__basic_future<Res&>;
1067 constexpr shared_future() noexcept :
1069 shared_future(
const shared_future& other) :
1072 base_type(_NEFORCE
move(other)) {}
1073 shared_future(shared_future&& other) noexcept :
1074 base_type(_NEFORCE
move(other)) {}
1076 shared_future& operator=(
const shared_future& other) {
1077 shared_future(other).swap(*
this);
1081 shared_future& operator=(shared_future&& other)
noexcept {
1082 shared_future(_NEFORCE
move(other)).swap(*
this);
1090 Res&
get()
const {
return this->get_result().get(); }
1097class shared_future<void> :
public inner::__basic_future<void> {
1098 using base_type = inner::__basic_future<void>;
1101 shared_future()
noexcept =
default;
1103 shared_future(
const shared_future& other) :
1106 base_type(_NEFORCE
move(other)) {}
1107 shared_future(shared_future&& other) noexcept :
1108 base_type(_NEFORCE
move(other)) {}
1110 shared_future& operator=(
const shared_future& other) {
1111 shared_future(other).swap(*
this);
1115 shared_future& operator=(shared_future&& other)
noexcept {
1116 shared_future(_NEFORCE
move(other)).swap(*
this);
1123 void get()
const { ignore = this->get_result(); }
1128template <
typename Res>
1129inner::__basic_future<Res>::__basic_future(
const shared_future<Res>& other) noexcept :
1130state_ptr(other.state_ptr) {}
1132template <
typename Res>
1133inner::__basic_future<Res>::__basic_future(shared_future<Res>&& other) noexcept :
1134state_ptr(_NEFORCE
move(other.state_ptr)) {}
1136template <
typename Res>
1137inner::__basic_future<Res>::__basic_future(future<Res>&& other) noexcept :
1138state_ptr(_NEFORCE
move(other.state_ptr)) {}
1141template <
typename Result>
1142shared_future<Result> future<Result>::share() noexcept {
1143 return shared_future<Result>(_NEFORCE
move(*
this));
1146template <
typename Res>
1147shared_future<Res&> future<Res&>::share() noexcept {
1148 return shared_future<Res&>(_NEFORCE
move(*
this));
1151inline shared_future<void> future<void>::share() noexcept {
return {_NEFORCE
move(*
this)}; }
1161template <
typename T>
1178template <
typename T>
1188template <
typename T>
1200template <
typename T>
1209NEFORCE_END_NAMESPACE__
future & operator=(future &&other) noexcept
移动赋值运算符
shared_future< Res > share() noexcept
转换为共享future
future(future &&other) noexcept
移动构造函数
constexpr future() noexcept
默认构造函数
const Res & get() const
获取常量引用结果
allocated_ptr< Alloc > allocate_guarded(Alloc &alloc)
分配内存并创建allocated_ptr
constexpr T * addressof(T &x) noexcept
获取对象的地址
future< async_result_t< Func, Args... > > async(launch policy, Func &&function, Args &&... args)
异步执行函数(指定策略)
enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
invoke_result_t< decay_t< Func >, decay_t< Args >... > async_result_t
异步调用结果类型推导
typename future_result< T >::type future_result_t
future结果类型别名
@ future_already_retrieved
future已经被获取
@ promise_already_satisfied
promise已经被满足
constexpr bool is_function_v
is_function的便捷变量模板
constexpr bool is_array_v
is_array的便捷变量模板
void call_once(once_flag &flag, Callable &&func, Args &&... args)
单次调用函数
milliseconds relative_time(int64_t sec, int64_t nsec, bool is_monotonic=false) noexcept
将绝对时间戳转换为相对延迟毫秒数
constexpr deferred_t deferred
deferred 常量
unsigned int uint32_t
32位无符号整数类型
void unreachable() noexcept
标记不可达代码路径
void rethrow_exception(const exception_ptr &p)
重新抛出异常
exception_ptr make_exception_ptr(Ex ex) noexcept
创建异常指针
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
typename inner::__invoke_result_aux< F, Args... >::type invoke_result_t
invoke_result的便捷别名
constexpr none_t none
默认空表示
@ reset
调用sqlite3_reset重置语句(用于预处理语句复用)
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void thread_exit_register(thread_exit_elt *elt, thread_exit_callback_t callback) noexcept
注册线程退出回调
typename decay< T >::type decay_t
decay的便捷别名
constexpr bool is_destructible_v
is_destructible的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
bool_constant< true > true_type
表示true的类型
void swap(unique_ptr< T, Deleter > &lhs, unique_ptr< T, Deleter > &rhs) noexcept
交换两个unique_ptr
function< float(float)> function
缓动函数类型:输入归一化时间 [0,1],输出进度 [0,1]
static constexpr duration zero() noexcept
获取零持续时间
exception(const char *info="")
构造函数
const char * type() const noexcept override
获取异常类型