...
This commit is contained in:
@@ -198,15 +198,36 @@ concept ret_expected_type_c = requires {
|
||||
// result of asynchronous callable
|
||||
|
||||
template <typename, typename = std::void_t<>>
|
||||
struct has_co_await_operator : std::false_type {};
|
||||
struct has_co_await_operator : std::false_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_co_await_operator<T, std::void_t<decltype(std::declval<T>().operator co_await())>> : std::true_type {};
|
||||
struct has_co_await_operator<T, std::void_t<decltype(std::declval<T>().operator co_await())>> : std::true_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_co_await_operator_v = has_co_await_operator<T>::value;
|
||||
|
||||
|
||||
template <typename T, bool>
|
||||
struct deduced_awaitable_ret_type;
|
||||
|
||||
template <typename T>
|
||||
struct deduced_awaitable_ret_type<T, true> {
|
||||
using type = decltype(std::declval<decltype(std::declval<T>().operator co_await())>().await_resume());
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct deduced_awaitable_ret_type<T, false> {
|
||||
using type = decltype(std::declval<T>().await_resume());
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
using deduced_awaitable_ret_type_t = typename deduced_awaitable_ret_type<T, has_co_await_operator_v<T>>::type;
|
||||
|
||||
|
||||
template <typename T, typename UT = void>
|
||||
concept result_awaiter_c = requires(T t, std::coroutine_handle<> hndl) {
|
||||
{ t.await_ready() } -> std::convertible_to<bool>;
|
||||
@@ -229,28 +250,33 @@ concept result_awaitable_c = requires(T t) {
|
||||
// { t.operator co_await() } -> result_awaiter_c<UT>;
|
||||
// };
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept awaitable_c = (!has_co_await_operator_v<T> || requires {
|
||||
std::declval<decltype(std::declval<T>().operator co_await())>().await_resume();
|
||||
}) && (has_co_await_operator_v<T> || requires { std::declval<T>().await_resume(); });
|
||||
|
||||
|
||||
|
||||
template <typename T, typename RT = void>
|
||||
concept awaitable_type_c =
|
||||
concept awaitable_ret_type_c =
|
||||
(!has_co_await_operator_v<T> ||
|
||||
std::same_as<decltype(std::declval<decltype(std::declval<T>().operator co_await())>().await_resume()), RT>) &&
|
||||
(has_co_await_operator_v<T> || std::same_as<decltype(std::declval<T>().await_resume()), RT>);
|
||||
|
||||
|
||||
static_assert(awaitable_type_c<asio::awaitable<void>>, "!!!");
|
||||
static_assert(awaitable_ret_type_c<asio::awaitable<void>>, "!!!");
|
||||
static_assert(awaitable_c<asio::awaitable<int>>, "!!!");
|
||||
|
||||
template <typename T, typename RT>
|
||||
concept awaitable_ret_expected_type_c = awaitable_c<T> && ret_expected_type_c<deduced_awaitable_ret_type_t<T>, RT>;
|
||||
|
||||
|
||||
template <typename T, typename UT = void>
|
||||
concept async_retval_c = result_awaitable_c<decltype(std::declval<T>().operator co_await())> || requires {
|
||||
[] -> auto {
|
||||
T t;
|
||||
co_await t;
|
||||
}();
|
||||
};
|
||||
// template <typename T, typename UT = void>
|
||||
// concept async_retval_c = result_awaiter_c<decltype(std::declval<T>().operator co_await()), UT>;
|
||||
|
||||
// template <typename T, typename UT = void>
|
||||
// concept async_retval_c = result_awaitable_c<T, UT> && ret_expected_c<UT>;
|
||||
}; // namespace snplib
|
||||
template <typename T, typename UT = void>
|
||||
concept async_retval_c = result_awaitable_c<T, UT> && ret_expected_c<UT>;
|
||||
|
||||
|
||||
|
||||
@@ -267,4 +293,4 @@ concept logger_c = requires(T t) {
|
||||
|
||||
|
||||
|
||||
} // namespace snplib
|
||||
}; // namespace snplib
|
||||
@@ -71,9 +71,9 @@ concept net_connection_c = requires(T t) {
|
||||
typename T::error_t;
|
||||
|
||||
// { t.send(std::declval<typename T::message_t>()) } -> async_retval_c<typename T::error_t>;
|
||||
{ t.send(std::declval<typename T::message_t>()) } -> awaitable_type_c<typename T::error_t>;
|
||||
{ t.send(std::declval<typename T::message_t>()) } -> awaitable_ret_type_c<typename T::error_t>;
|
||||
// { t.recv() } -> async_retval_c<typename T::message_t>;
|
||||
{ t.recv() } -> awaitable_type_c<typename T::message_t>;
|
||||
{ t.recv() } -> awaitable_ret_type_c<typename T::message_t>;
|
||||
|
||||
// [] {
|
||||
// typename T::message_t msg;
|
||||
|
||||
Reference in New Issue
Block a user