...
This commit is contained in:
@@ -198,15 +198,36 @@ concept ret_expected_type_c = requires {
|
|||||||
// result of asynchronous callable
|
// result of asynchronous callable
|
||||||
|
|
||||||
template <typename, typename = std::void_t<>>
|
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>
|
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>
|
template <typename T>
|
||||||
constexpr bool has_co_await_operator_v = has_co_await_operator<T>::value;
|
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>
|
template <typename T, typename UT = void>
|
||||||
concept result_awaiter_c = requires(T t, std::coroutine_handle<> hndl) {
|
concept result_awaiter_c = requires(T t, std::coroutine_handle<> hndl) {
|
||||||
{ t.await_ready() } -> std::convertible_to<bool>;
|
{ 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>;
|
// { 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>
|
template <typename T, typename RT = void>
|
||||||
concept awaitable_type_c =
|
concept awaitable_ret_type_c =
|
||||||
(!has_co_await_operator_v<T> ||
|
(!has_co_await_operator_v<T> ||
|
||||||
std::same_as<decltype(std::declval<decltype(std::declval<T>().operator co_await())>().await_resume()), RT>) &&
|
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>);
|
(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>
|
// template <typename T, typename UT = void>
|
||||||
// concept async_retval_c = result_awaiter_c<decltype(std::declval<T>().operator co_await()), UT>;
|
// concept async_retval_c = result_awaiter_c<decltype(std::declval<T>().operator co_await()), UT>;
|
||||||
|
|
||||||
// template <typename T, typename UT = void>
|
template <typename T, typename UT = void>
|
||||||
// concept async_retval_c = result_awaitable_c<T, UT> && ret_expected_c<UT>;
|
concept async_retval_c = result_awaitable_c<T, UT> && ret_expected_c<UT>;
|
||||||
}; // namespace snplib
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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;
|
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>()) } -> 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() } -> 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;
|
// typename T::message_t msg;
|
||||||
|
|||||||
Reference in New Issue
Block a user