1#ifndef NEFORCE_CORE_ASYNC_GENERATOR_HPP__
2#define NEFORCE_CORE_ASYNC_GENERATOR_HPP__
16#ifdef NEFORCE_STANDARD_20
22NEFORCE_BEGIN_NAMESPACE__
64 if (
token !=
nullptr &&
token->is_cancelled()) {
65 NEFORCE_THROW_EXCEPTION(
exception(
"Operation cancelled"));
73 atomic<size_t> ref_count{1};
91 state_(new state()) {}
98 state_(other.state_) {
99 if (state_ !=
nullptr) {
115 state_ = other.state_;
116 if (state_ !=
nullptr) {
131 if (state_ !=
nullptr) {
158template <
typename T,
typename F>
161template <
typename T,
typename Pred>
241 using value_type = T;
244 using reference = T&;
283 return *
handle.promise().current_value;
323 handle_(other.handle_) {
324 other.handle_ =
nullptr;
340 handle_ = other.handle_;
341 other.handle_ =
nullptr;
365 if (handle_.promise().exception) {
368 if (handle_.done()) {
387 template <
typename F>
389 return inner::generator_map(
move(*
this),
move(func));
398 template <
typename Pred>
400 return inner::generator_filter(
move(*
this),
move(pred));
429 template <
typename F>
431 for (
auto&& value: *
this) {
432 func(_NEFORCE
forward<
decltype(value)>(value));
444 template <
typename Acc,
typename F>
446 Acc result = _NEFORCE
move(init);
447 for (
auto&& value: *
this) {
448 result = func(_NEFORCE
move(result), _NEFORCE
forward<
decltype(value)>(value));
458template <
typename T,
typename F>
460 for (
auto&& value: source) {
461 co_yield func(_NEFORCE
forward<
decltype(value)>(value));
465template <
typename T,
typename Pred>
467 for (
auto&& value: source) {
477 for (
auto&& value: source) {
489 for (
auto&& value: source) {
500 for (
auto&& value: source) {
503 for (
auto&& value: other) {
624 handle.promise().continuation = continuation;
633 if (
handle.promise().exception) {
636 return _NEFORCE
move(*
handle.promise().result);
656 handle_(other.handle_) {
657 other.handle_ =
nullptr;
673 handle_ = other.handle_;
674 other.handle_ =
nullptr;
701 NEFORCE_NODISCARD
bool done() const noexcept {
return handle_.done(); }
707 if (handle_ && !handle_.done()) {
717 while (!handle_.done()) {
720 if (handle_.promise().exception) {
723 return _NEFORCE
move(*handle_.promise().result);
732 handle_.promise().set_cancellation_token(&token);
740 NEFORCE_NODISCARD
bool is_cancelled() const noexcept {
return handle_ && handle_.promise().is_cancelled(); }
750 struct promise_type {
765 struct final_awaiter {
780 void return_void()
noexcept {}
791 handle.promise().continuation = continuation;
796 if (
handle.promise().exception) {
809 task(task&& other) noexcept :
810 handle_(other.handle_) {
811 other.handle_ =
nullptr;
822 handle_ = other.handle_;
823 other.handle_ =
nullptr;
834 task(
const task&) =
delete;
837 awaiter
operator co_await() {
return awaiter{handle_}; }
839 NEFORCE_NODISCARD
bool done()
const {
return handle_.
done(); }
842 if (handle_ && !handle_.done()) {
848 while (!handle_.done()) {
851 if (handle_.promise().exception) {
858 handle_.promise().set_cancellation_token(&token);
862 NEFORCE_NODISCARD
bool is_cancelled()
const {
return handle_ && handle_.promise().is_cancelled(); }
874template <
typename... Tasks>
875auto when_all(Tasks... tasks) ->
task<tuple<
typename Tasks::promise_type::value_type...>> {
876 tuple<
typename Tasks::promise_type::value_type...> results;
879 ((_NEFORCE
get<Is>(results) = _NEFORCE
get<Is>(task_tuple).get()), ...);
896template <
typename T,
typename Factory>
903 for (
size_t attempt = 0; attempt < max_attempts; ++attempt) {
905 co_return co_await factory();
909 if (should_retry && !should_retry(last_exception)) {
912 if (attempt == max_attempts - 1) {
923NEFORCE_END_NAMESPACE__
void cancel() noexcept
请求取消
check_awaiter check() const
获取取消检查等待器
~cancellation_token()
析构函数,释放状态
cancellation_token & operator=(const cancellation_token &other)
拷贝赋值运算符
bool is_cancelled() const noexcept
检查是否已被取消
cancellation_token()
默认构造函数,创建新的取消令牌
cancellation_token(const cancellation_token &other)
拷贝构造函数,共享状态
generator(coroutine_handle< promise_type > h)
从协程句柄构造
generator skip(const size_t n)
跳过前n个元素
generator filter(Pred pred)
过滤
generator take(const size_t n)
取前n个元素
generator< invoke_result_t< F, T > > map(F func)
映射变换
generator & operator=(generator &&other) noexcept
移动赋值运算符
generator chain(generator other)
连接两个生成器
void for_each(F &&func)
遍历每个元素
generator(generator &&other) noexcept
移动构造函数
Acc fold(Acc init, F &&func)
折叠(归约)
void set_cancellation_token(cancellation_token &token)
设置取消令牌
task & operator=(task &&other) noexcept
移动赋值运算符
task(task &&other) noexcept
移动构造函数
bool done() const noexcept
检查任务是否已完成
bool is_cancelled() const noexcept
检查任务是否被取消
task(coroutine_handle< promise_type > h)
从协程句柄构造
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr T * addressof(T &x) noexcept
获取对象的地址
enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
std::coroutine_handle< Promise > coroutine_handle
协程句柄
task< T > retry(Factory factory, const size_t max_attempts, const function< bool(const exception_ptr &)> &should_retry={})
带重试的异步操作
auto when_all(Tasks... tasks) -> task< tuple< typename Tasks::promise_type::value_type... > >
等待所有任务完成
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
NEFORCE_NORETURN void rethrow_exception(const exception_ptr &p)
重新抛出异常
exception_ptr current_exception() noexcept
获取当前异常
integer_sequence< size_t, Values... > index_sequence
索引序列
make_index_sequence< sizeof...(Types)> index_sequence_for
根据类型参数包生成索引序列
constexpr bool is_invocable_r_v
is_invocable_r的便捷变量模板
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_relaxed
宽松内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
thread::native_handle_type handle() noexcept
获取当前线程句柄
constexpr tuple< unwrap_ref_decay_t< Types >... > make_tuple(Types &&... args)
从参数创建元组
bool await_ready() const noexcept
检查是否可立即恢复
const cancellation_token * token
令牌指针
void await_resume() const
恢复时执行的操作
void await_suspend(coroutine_handle<> h) const noexcept
暂停协程(实际上从不暂停)
T & operator*() const noexcept
解引用,获取当前值
bool operator!=(const iterator &other) const noexcept
不等比较
bool operator==(const iterator &other) const noexcept
相等比较
coroutine_handle< promise_type > handle
协程句柄
iterator(coroutine_handle< promise_type > h)
从协程句柄构造
T * operator->() const noexcept
箭头操作符
iterator & operator++()
前置递增,恢复协程获取下一个值
optional< T > current_value
当前产生的值
void return_void() noexcept
返回void(生成器不返回值)
suspend_always yield_value(T value)
产生一个值
exception_ptr exception
异常指针
void unhandled_exception()
处理未捕获的异常
suspend_always final_suspend() noexcept
最终暂停点
suspend_always initial_suspend() noexcept
初始暂停点
generator get_return_object()
获取生成器对象
coroutine_handle< promise_type > handle
协程句柄
bool await_ready() const noexcept
检查是否可立即恢复
coroutine_handle await_suspend(coroutine_handle<> continuation) noexcept
暂停时执行的操作
void await_resume() noexcept
恢复时执行的操作
bool await_ready() noexcept
检查是否可立即恢复
void await_suspend(coroutine_handle< promise_type > h) noexcept
暂停时执行的操作
void unhandled_exception() noexcept
处理未捕获的异常
void return_value(T value)
设置返回值
void set_cancellation_token(cancellation_token *t) noexcept
设置取消令牌
final_awaiter final_suspend() noexcept
最终暂停点
cancellation_token * token
取消令牌
task get_return_object()
获取任务对象
coroutine_handle continuation
继续执行的协程
bool is_cancelled() const noexcept
检查是否已取消
suspend_always initial_suspend() noexcept
初始暂停点
exception_ptr exception
异常指针