This commit is contained in:
Timur A. Fatkhullin
2026-10-01 00:39:19 +03:00
parent af04681b3c
commit bc8c6b64ec
2 changed files with 43 additions and 17 deletions

View File

@@ -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

View File

@@ -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;