@@ -360,7 +360,7 @@ AUTOLINK_SUPPORT = YES | |||
# diagrams that involve STL classes more complete and accurate. | |||
# The default value is: NO. | |||
BUILTIN_STL_SUPPORT = NO | |||
BUILTIN_STL_SUPPORT = YES | |||
# If you use Microsoft's C++/CLI language, you should set this option to YES to | |||
# enable parsing support. | |||
@@ -491,7 +491,7 @@ EXTRACT_PACKAGE = NO | |||
# included in the documentation. | |||
# The default value is: NO. | |||
EXTRACT_STATIC = NO | |||
EXTRACT_STATIC = YES | |||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined | |||
# locally in source files will be included in the documentation. If set to NO, | |||
@@ -539,7 +539,7 @@ HIDE_UNDOC_CLASSES = NO | |||
# documentation. | |||
# The default value is: NO. | |||
HIDE_FRIEND_COMPOUNDS = NO | |||
HIDE_FRIEND_COMPOUNDS = YES | |||
# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any | |||
# documentation blocks found inside the body of a function. If set to NO, these | |||
@@ -582,7 +582,7 @@ HIDE_COMPOUND_REFERENCE= NO | |||
# the files that are included by a file in the documentation of that file. | |||
# The default value is: YES. | |||
SHOW_INCLUDE_FILES = YES | |||
SHOW_INCLUDE_FILES = NO | |||
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each | |||
# grouped member an include statement to the documentation, telling the reader | |||
@@ -856,24 +856,11 @@ INPUT_ENCODING = UTF-8 | |||
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd, | |||
# *.vhdl, *.ucf, *.qsf and *.ice. | |||
FILE_PATTERNS = *.c \ | |||
*.cc \ | |||
*.cxx \ | |||
*.cpp \ | |||
*.c++ \ | |||
*.java \ | |||
*.ii \ | |||
*.ixx \ | |||
*.ipp \ | |||
*.i++ \ | |||
FILE_PATTERNS = *.java \ | |||
*.idl \ | |||
*.ddl \ | |||
*.odl \ | |||
*.h \ | |||
*.hh \ | |||
*.hxx \ | |||
*.hpp \ | |||
*.h++ \ | |||
*.cs \ | |||
*.d \ | |||
*.php \ | |||
@@ -916,7 +903,9 @@ RECURSIVE = NO | |||
# Note that relative paths are relative to the directory from which doxygen is | |||
# run. | |||
EXCLUDE = | |||
EXCLUDE = channel_v1.h \ | |||
event_v1.h \ | |||
mutex_v1.h | |||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or | |||
# directories that are symbolic links (a Unix file system feature) are excluded |
@@ -1,5 +1,7 @@ | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
namespace detail | |||
@@ -57,3 +59,6 @@ RESUMEF_NS | |||
}; | |||
} | |||
} | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
@@ -1,7 +1,10 @@ | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
template<class _Ty> | |||
struct awaitable_impl_t | |||
{ | |||
@@ -52,6 +55,7 @@ RESUMEF_NS | |||
} | |||
}; | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
template<class _Ty> | |||
struct [[nodiscard]] awaitable_t<_Ty&> : public awaitable_impl_t<_Ty&> | |||
{ | |||
@@ -76,4 +80,5 @@ RESUMEF_NS | |||
this->_state = nullptr; | |||
} | |||
}; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
} |
@@ -11,7 +11,7 @@ namespace detail | |||
inline namespace channel_v2 | |||
{ | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
/** | |||
* @brief 可传递数据的模板信号量。 | |||
@@ -62,11 +62,11 @@ inline namespace channel_v2 | |||
template<class U | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
COMMA_RESUMEF_ENABLE_IF(std::is_constructible_v<value_type, U&&>) | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_REQUIRES(std::is_constructible_v<_Ty, U&&>) | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
write_awaiter operator << (U&& val) const noexcept(std::is_move_constructible_v<U>); | |||
/** | |||
@@ -79,11 +79,11 @@ inline namespace channel_v2 | |||
template<class U | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
COMMA_RESUMEF_ENABLE_IF(std::is_constructible_v<value_type, U&&>) | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_REQUIRES(std::is_constructible_v<_Ty, U&&>) | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
write_awaiter write(U&& val) const noexcept(std::is_move_constructible_v<U>); | |||
@@ -103,7 +103,7 @@ inline namespace channel_v2 | |||
channel_t& operator = (channel_t&&) = default; | |||
private: | |||
std::shared_ptr<channel_type> _chan; | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
}; | |||
@@ -113,7 +113,7 @@ inline namespace channel_v2 | |||
struct channel_t<void, _Option, _OptimizationThread> | |||
{ | |||
}; | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
/** | |||
* @brief 利用channel_t重定义的信号量。 |
@@ -1,8 +1,10 @@ | |||
| |||
#pragma once | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
template <typename T> | |||
struct counted_ptr | |||
{ |
@@ -1,7 +1,10 @@ | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
struct get_current_scheduler_awaitor | |||
{ | |||
bool await_ready() const noexcept |
@@ -8,6 +8,7 @@ | |||
#define RESUMEF_NS namespace resumef | |||
#endif | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
struct scheduler_t; | |||
@@ -26,24 +27,29 @@ RESUMEF_NS | |||
template<class _Ty = void> | |||
struct awaitable_t; | |||
//获得当前线程下的调度器 | |||
scheduler_t* this_scheduler(); | |||
struct state_base_t; | |||
struct switch_scheduler_t; | |||
#else //DOXYGEN_SKIP_PROPERTY | |||
namespace resumef { | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
template<typename _PromiseT = void> | |||
using coroutine_handle = std::experimental::coroutine_handle<_PromiseT>; | |||
using suspend_always = std::experimental::suspend_always; | |||
using suspend_never = std::experimental::suspend_never; | |||
struct state_base_t; | |||
struct switch_scheduler_t; | |||
template<class... _Mutexes> | |||
using scoped_lock = std::scoped_lock<_Mutexes...>; | |||
constexpr size_t _Version = LIB_RESUMEF_VERSION; | |||
//获得当前线程下的调度器 | |||
scheduler_t* this_scheduler(); | |||
} | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
#if RESUMEF_DEBUG_COUNTER | |||
extern std::mutex g_resumef_cout_mutex; | |||
extern std::atomic<intptr_t> g_resumef_state_count; | |||
@@ -73,3 +79,5 @@ RESUMEF_NS | |||
} | |||
#include "exception.inl" | |||
#endif //DOXYGEN_SKIP_PROPERTY |
@@ -1,5 +1,6 @@ | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
namespace detail | |||
@@ -9,6 +10,8 @@ RESUMEF_NS | |||
inline namespace event_v2 | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
struct event_t | |||
{ | |||
using event_impl_ptr = std::shared_ptr<detail::event_v2_impl>; |
@@ -1,7 +1,10 @@ | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
enum struct error_code | |||
{ | |||
none, |
@@ -1,8 +1,11 @@ | |||
| |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
template<class _Ty> | |||
struct [[nodiscard]] future_t | |||
{ | |||
@@ -40,7 +43,7 @@ RESUMEF_NS | |||
}; | |||
} | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
namespace std { | |||
namespace experimental { | |||
@@ -56,4 +59,4 @@ namespace std { | |||
}; | |||
} | |||
} // namespace std::experimental | |||
#endif //DOXYGEN_SKIP_PROPERTY |
@@ -9,11 +9,16 @@ | |||
#pragma push_macro("new") | |||
#undef new | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
template <typename _Ty, typename promise_type> | |||
struct generator_iterator; | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
template<typename promise_type> | |||
struct generator_iterator<void, promise_type> | |||
{ | |||
@@ -92,6 +97,7 @@ RESUMEF_NS | |||
return this->_Coro.promise()._CurrentValue; | |||
} | |||
}; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
template <typename _Ty, typename _Alloc> | |||
struct generator_t | |||
@@ -99,6 +105,7 @@ RESUMEF_NS | |||
using value_type = _Ty; | |||
using state_type = state_generator_t; | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
struct promise_type | |||
{ | |||
using value_type = _Ty; | |||
@@ -247,6 +254,7 @@ RESUMEF_NS | |||
counted_ptr<state_type> _state = state_generator_t::_Alloc_state(); | |||
#endif | |||
}; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
typedef generator_iterator<_Ty, promise_type> iterator; | |||
@@ -314,6 +322,8 @@ RESUMEF_NS | |||
#pragma pop_macro("new") | |||
#pragma pack(pop) | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
namespace std { | |||
namespace experimental { | |||
@@ -324,3 +334,5 @@ namespace std { | |||
}; | |||
} | |||
} // namespace std::experimental | |||
#endif //DOXYGEN_SKIP_PROPERTY |
@@ -10,7 +10,7 @@ RESUMEF_NS | |||
inline namespace mutex_v2 | |||
{ | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
/** | |||
* @brief 提示手工解锁,故相关的lock()函数不再返回scoped_unlock_t。 | |||
*/ | |||
@@ -142,7 +142,7 @@ RESUMEF_NS | |||
template<class... _Mtxs | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
static future_t<scoped_unlock_t<_Mtxs...>> lock(_Mtxs&... mtxs); | |||
@@ -155,7 +155,7 @@ RESUMEF_NS | |||
template<class... _Mtxs | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
static future_t<> lock(adopt_manual_unlock_t manual_unlock_tag, _Mtxs&... mtxs); | |||
@@ -167,7 +167,7 @@ RESUMEF_NS | |||
template<class... _Mtxs | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
static future_t<> unlock(_Mtxs&... mtxs); | |||
@@ -181,7 +181,7 @@ RESUMEF_NS | |||
template<class... _Mtxs | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
static scoped_unlock_t<_Mtxs...> lock(void* unique_address, _Mtxs&... mtxs); | |||
@@ -194,7 +194,7 @@ RESUMEF_NS | |||
template<class... _Mtxs | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
static void lock(adopt_manual_unlock_t manual_unlock_tag, void* unique_address, _Mtxs&... mtxs); | |||
@@ -206,7 +206,7 @@ RESUMEF_NS | |||
template<class... _Mtxs | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
> | |||
static void unlock(void* unique_address, _Mtxs&... mtxs); | |||
@@ -232,7 +232,7 @@ RESUMEF_NS | |||
template<class... _Mtxs> friend struct scoped_unlock_t; | |||
mutex_impl_ptr _mutex; | |||
#endif | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
}; | |||
} | |||
} |
@@ -3,6 +3,7 @@ | |||
#pragma push_macro("new") | |||
#undef new | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
struct suspend_on_initial; | |||
@@ -74,7 +75,7 @@ RESUMEF_NS | |||
void return_void(); //co_return; | |||
suspend_always yield_value(); | |||
}; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
} | |||
#pragma pop_macro("new") |
@@ -1,27 +1,39 @@ | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
struct task_base_t; | |||
/** | |||
* @brief 协程任务的基类。 | |||
*/ | |||
struct task_base_t | |||
{ | |||
task_base_t() = default; | |||
virtual ~task_base_t(); | |||
state_base_t* get_state() const noexcept | |||
{ | |||
return _state.get(); | |||
} | |||
protected: | |||
friend scheduler_t; | |||
counted_ptr<state_base_t> _state; | |||
}; | |||
#endif | |||
//---------------------------------------------------------------------------------------------- | |||
/** | |||
* @brief 协程任务类。 | |||
* @details 每启动一个新的协程,则对应一个协程任务类。\n | |||
* 一方面,task_t<>用于标记协程是否执行完毕;\n | |||
* 另一方面,对于通过函数对象(functor/lambda)启动的协程,有很大概率,此协程的内部变量,依赖此函数对象的生存期。\n | |||
* tast_t<>的针对函数对象的特化版本,会持有此函数对象的拷贝,从而保证协程内部变量的生存期。从而减少外部使用协程函数对象的工作量。\n | |||
* 如果不希望task_t<>持有此函数对象,则通过调用此函数对象来启动协程,即:\n | |||
* go functor; \n | |||
* 替换为\n | |||
* go functor(); | |||
*/ | |||
template<class _Ty, class = std::void_t<>> | |||
struct task_t; | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
template<class _Ty> | |||
struct task_t<_Ty, std::void_t<traits::is_future<std::remove_reference_t<_Ty>>>> : public task_base_t | |||
{ | |||
@@ -79,4 +91,5 @@ RESUMEF_NS | |||
this->initialize(f); | |||
} | |||
}; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
} |
@@ -105,7 +105,7 @@ RESUMEF_NS | |||
void scheduler_t::new_task(task_base_t * task) | |||
{ | |||
state_base_t* sptr = task->get_state(); | |||
state_base_t* sptr = task->_state.get(); | |||
sptr->set_scheduler(this); | |||
{ | |||
@@ -152,7 +152,7 @@ RESUMEF_NS | |||
void scheduler_t::add_switch(std::unique_ptr<task_base_t> task) | |||
{ | |||
state_base_t* sptr = task->get_state(); | |||
state_base_t* sptr = task->_state.get(); | |||
scoped_lock<spinlock> __guard(_lock_ready); | |||
this->_ready_task.emplace(sptr, std::move(task)); |
@@ -89,6 +89,7 @@ RESUMEF_NS | |||
#endif | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
namespace detail | |||
{ | |||
template<class _Ty, class _Cont = std::vector<_Ty>> | |||
@@ -175,6 +176,7 @@ RESUMEF_NS | |||
#undef LOCK_ASSEMBLE_AWAIT | |||
#undef LOCK_ASSEMBLE_RETURN | |||
} | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
template<class _Ty, class _Cont = std::vector<_Ty>, class _Assemble = detail::_LockVectorAssembleT<_Ty, _Cont>> | |||
class scoped_lock_range { // class with destructor that unlocks mutexes |
@@ -1,7 +1,10 @@ | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
struct state_base_t | |||
{ | |||
using _Alloc_char = std::allocator<char>; | |||
@@ -251,6 +254,7 @@ RESUMEF_NS | |||
void set_exception_internal(std::exception_ptr e); | |||
}; | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
template <typename _Ty> | |||
struct state_t<_Ty&> final : public state_future_t | |||
{ | |||
@@ -314,5 +318,6 @@ RESUMEF_NS | |||
private: | |||
std::exception_ptr _exception; | |||
}; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
} | |||
@@ -1,7 +1,10 @@ | |||
#pragma once | |||
#pragma once | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
struct timer_manager; | |||
typedef std::shared_ptr<timer_manager> timer_mgr_ptr; | |||
typedef std::weak_ptr<timer_manager> timer_mgr_wptr; | |||
@@ -11,6 +14,9 @@ RESUMEF_NS | |||
typedef std::chrono::system_clock timer_clock_type; | |||
typedef std::function<void(bool)> timer_callback_type; | |||
/** | |||
* @brief 定时器对象。 | |||
*/ | |||
struct timer_target : public std::enable_shared_from_this<timer_target> | |||
{ | |||
friend timer_manager; | |||
@@ -46,22 +52,28 @@ RESUMEF_NS | |||
timer_target & operator = (const timer_target &) = delete; | |||
timer_target & operator = (timer_target && right_) = delete; | |||
}; | |||
typedef std::shared_ptr<timer_target> timer_target_ptr; | |||
typedef std::weak_ptr<timer_target> timer_target_wptr; | |||
} | |||
/** | |||
* @brief 定时器句柄。 | |||
* @details 对定时器对象和定时器管理器都采用弱引用。 | |||
*/ | |||
struct timer_handler | |||
{ | |||
private: | |||
timer_mgr_wptr _manager; | |||
detail::timer_target_wptr _target; | |||
public: | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
timer_handler() = default; | |||
timer_handler(const timer_handler &) = default; | |||
timer_handler(timer_handler && right_) noexcept; | |||
timer_handler & operator = (const timer_handler &) = default; | |||
timer_handler & operator = (timer_handler && right_) noexcept; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
timer_handler(timer_manager * manager_, const detail::timer_target_ptr & target_); | |||
void reset(); | |||
@@ -69,8 +81,12 @@ RESUMEF_NS | |||
bool expired() const; | |||
}; | |||
/** | |||
* @brief 定时器管理器。 | |||
*/ | |||
struct timer_manager : public std::enable_shared_from_this<timer_manager> | |||
{ | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
typedef detail::timer_target timer_target; | |||
typedef detail::timer_target_ptr timer_target_ptr; | |||
typedef detail::timer_clock_type clock_type; | |||
@@ -79,12 +95,8 @@ RESUMEF_NS | |||
typedef std::vector<timer_target_ptr> timer_vector_type; | |||
typedef std::multimap<clock_type::time_point, timer_target_ptr> timer_map_type; | |||
protected: | |||
spinlock _added_mtx; | |||
timer_vector_type _added_timers; | |||
#endif | |||
public: | |||
timer_map_type _runing_timers; | |||
timer_manager(); | |||
~timer_manager(); | |||
@@ -118,6 +130,7 @@ RESUMEF_NS | |||
void clear(); | |||
void update(); | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
template<class _Cb> | |||
timer_target_ptr add_(const duration_type & dt_, _Cb && cb_) | |||
{ | |||
@@ -129,8 +142,13 @@ RESUMEF_NS | |||
return add_(std::make_shared<timer_target>(tp_, std::forward<_Cb>(cb_))); | |||
} | |||
private: | |||
spinlock _added_mtx; | |||
timer_vector_type _added_timers; | |||
timer_map_type _runing_timers; | |||
timer_target_ptr add_(const timer_target_ptr & sptr); | |||
static void call_target_(const timer_target_ptr & sptr, bool canceld); | |||
#endif | |||
}; | |||
@@ -12,6 +12,7 @@ RESUMEF_NS | |||
//最最重要的,要统一ranged when_any的返回值,还得做一个运行时通过下标设置std::variant<>的东西 | |||
//std::any除了内存布局不太理想,其他方面几乎没缺点(在此应用下) | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
RESUMEF_NS | |||
{ | |||
using when_any_pair = std::pair<intptr_t, any_t>; | |||
@@ -248,8 +249,16 @@ RESUMEF_NS | |||
} | |||
} | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
#ifndef DOXYGEN_SKIP_PROPERTY | |||
inline namespace when_v2 | |||
{ | |||
#else | |||
struct when | |||
{ | |||
#endif | |||
template<_WhenTaskT... _Awaitable | |||
COMMA_RESUMEF_ENABLE_IF(std::conjunction_v<detail::is_when_task<_Awaitable>...>) | |||
> |