Skip to content

Commit 3bcdd62

Browse files
Cra3zdietmarkuehl
andauthored
Implement get_await_completion_adaptor (#226)
* Implement `get_await_completion_adaptor` * Fix CI error * Add a workaround about `has_completions` for clang 22 --------- Co-authored-by: Dietmar Kühl <dietmar.kuehl@me.com>
1 parent 7140868 commit 3bcdd62

4 files changed

Lines changed: 79 additions & 5 deletions

File tree

include/beman/execution/detail/as_awaitable.hpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,26 @@
99
import std;
1010
#else
1111
#include <coroutine>
12+
#include <functional>
1213
#include <type_traits>
1314
#include <utility>
1415
#endif
1516
#ifdef BEMAN_HAS_MODULES
1617
import beman.execution.detail.awaitable_sender;
18+
import beman.execution.detail.get_await_completion_adaptor;
19+
import beman.execution.detail.get_env;
20+
import beman.execution.detail.query_with_default;
1721
import beman.execution.detail.is_awaitable;
22+
import beman.execution.detail.sender;
1823
import beman.execution.detail.sender_awaitable;
1924
import beman.execution.detail.unspecified_promise;
2025
#else
2126
#include <beman/execution/detail/awaitable_sender.hpp>
27+
#include <beman/execution/detail/get_await_completion_adaptor.hpp>
28+
#include <beman/execution/detail/get_env.hpp>
29+
#include <beman/execution/detail/query_with_default.hpp>
2230
#include <beman/execution/detail/is_awaitable.hpp>
31+
#include <beman/execution/detail/sender.hpp>
2332
#include <beman/execution/detail/sender_awaitable.hpp>
2433
#include <beman/execution/detail/unspecified_promise.hpp>
2534
#endif
@@ -40,12 +49,25 @@ struct as_awaitable_t {
4049
Promise>,
4150
"as_awaitable must return an awaitable");
4251
return ::std::forward<Expr>(expr).as_awaitable(promise);
43-
} else if constexpr (::beman::execution::detail::
44-
is_awaitable<Expr, ::beman::execution::detail::unspecified_promise> ||
45-
!::beman::execution::detail::awaitable_sender<Expr, Promise>) {
46-
return ::std::forward<Expr>(expr);
52+
} else if constexpr (::beman::execution::sender<Expr> &&
53+
!::beman::execution::detail::
54+
is_awaitable<Expr, ::beman::execution::detail::unspecified_promise>) {
55+
auto adaptor =
56+
::beman::execution::detail::query_with_default(::beman::execution::get_await_completion_adaptor,
57+
::beman::execution::get_env(expr),
58+
::std::identity{});
59+
using sender_t = ::std::invoke_result_t<decltype(adaptor), Expr>;
60+
if constexpr (::beman::execution::detail::awaitable_sender<sender_t, Promise>) {
61+
return ::beman::execution::detail::sender_awaitable<sender_t, Promise>{
62+
adaptor(::std::forward<Expr>(expr)), promise};
63+
} else if constexpr (::beman::execution::detail::awaitable_sender<Expr, Promise>) {
64+
return ::beman::execution::detail::sender_awaitable<Expr, Promise>{::std::forward<Expr>(expr),
65+
promise};
66+
} else {
67+
return ::std::forward<Expr>(expr);
68+
}
4769
} else {
48-
return ::beman::execution::detail::sender_awaitable<Expr, Promise>{::std::forward<Expr>(expr), promise};
70+
return ::std::forward<Expr>(expr);
4971
}
5072
}
5173
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// include/beman/execution/detail/get_await_completion_adaptor.hpp -*-C++-*-
2+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
#ifndef INCLUDED_BEMAN_EXECUTION_DETAIL_GET_AWAIT_COMPLETION_ADAPTOR
5+
#define INCLUDED_BEMAN_EXECUTION_DETAIL_GET_AWAIT_COMPLETION_ADAPTOR
6+
7+
#include <beman/execution/detail/common.hpp>
8+
#ifdef BEMAN_HAS_IMPORT_STD
9+
import std;
10+
#else
11+
#include <utility>
12+
#endif
13+
#ifdef BEMAN_HAS_MODULES
14+
import beman.execution.detail.forwarding_query;
15+
#else
16+
#include <beman/execution/detail/forwarding_query.hpp>
17+
#endif
18+
19+
// ----------------------------------------------------------------------------
20+
21+
namespace beman::execution {
22+
struct get_await_completion_adaptor_t {
23+
template <typename Env>
24+
requires requires(Env&& env, const get_await_completion_adaptor_t& g) {
25+
{ ::std::as_const(env).query(g) } noexcept;
26+
}
27+
auto operator()(Env&& env) const noexcept {
28+
return ::std::as_const(env).query(*this);
29+
}
30+
static constexpr auto query(const ::beman::execution::forwarding_query_t&) noexcept -> bool { return true; }
31+
};
32+
33+
inline constexpr get_await_completion_adaptor_t get_await_completion_adaptor{};
34+
} // namespace beman::execution
35+
36+
// ----------------------------------------------------------------------------
37+
38+
#endif // INCLUDED_BEMAN_EXECUTION_DETAIL_GET_AWAIT_COMPLETION_ADAPTOR

src/beman/execution/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ target_sources(
7979
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/fwd_env.hpp
8080
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/gather_signatures.hpp
8181
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_allocator.hpp
82+
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_await_completion_adaptor.hpp
8283
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_awaiter.hpp
8384
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_completion_scheduler.hpp
8485
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_completion_signatures.hpp
@@ -259,6 +260,7 @@ if(BEMAN_USE_MODULES)
259260
fwd_env.cppm
260261
gather_signatures.cppm
261262
get_allocator.cppm
263+
get_await_completion_adaptor.cppm
262264
get_awaiter.cppm
263265
get_completion_scheduler.cppm
264266
get_completion_signatures.cppm
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module;
2+
// src/beman/execution/get_await_completion_adaptor.cppm -*-C++-*-
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
#include <beman/execution/detail/get_await_completion_adaptor.hpp>
6+
7+
export module beman.execution.detail.get_await_completion_adaptor;
8+
9+
namespace beman::execution {
10+
export using beman::execution::get_await_completion_adaptor_t;
11+
export using beman::execution::get_await_completion_adaptor;
12+
} // namespace beman::execution

0 commit comments

Comments
 (0)