Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions include/beman/execution/detail/as_awaitable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,26 @@
import std;
#else
#include <coroutine>
#include <functional>
#include <type_traits>
#include <utility>
#endif
#ifdef BEMAN_HAS_MODULES
import beman.execution.detail.awaitable_sender;
import beman.execution.detail.get_await_completion_adaptor;
import beman.execution.detail.get_env;
import beman.execution.detail.query_with_default;
import beman.execution.detail.is_awaitable;
import beman.execution.detail.sender;
import beman.execution.detail.sender_awaitable;
import beman.execution.detail.unspecified_promise;
#else
#include <beman/execution/detail/awaitable_sender.hpp>
#include <beman/execution/detail/get_await_completion_adaptor.hpp>
#include <beman/execution/detail/get_env.hpp>
#include <beman/execution/detail/query_with_default.hpp>
#include <beman/execution/detail/is_awaitable.hpp>
#include <beman/execution/detail/sender.hpp>
#include <beman/execution/detail/sender_awaitable.hpp>
#include <beman/execution/detail/unspecified_promise.hpp>
#endif
Expand All @@ -40,12 +49,25 @@ struct as_awaitable_t {
Promise>,
"as_awaitable must return an awaitable");
return ::std::forward<Expr>(expr).as_awaitable(promise);
} else if constexpr (::beman::execution::detail::
is_awaitable<Expr, ::beman::execution::detail::unspecified_promise> ||
!::beman::execution::detail::awaitable_sender<Expr, Promise>) {
return ::std::forward<Expr>(expr);
} else if constexpr (::beman::execution::sender<Expr> &&
!::beman::execution::detail::
is_awaitable<Expr, ::beman::execution::detail::unspecified_promise>) {
auto adaptor =
::beman::execution::detail::query_with_default(::beman::execution::get_await_completion_adaptor,
::beman::execution::get_env(expr),
::std::identity{});
using sender_t = ::std::invoke_result_t<decltype(adaptor), Expr>;
if constexpr (::beman::execution::detail::awaitable_sender<sender_t, Promise>) {
return ::beman::execution::detail::sender_awaitable<sender_t, Promise>{
adaptor(::std::forward<Expr>(expr)), promise};
} else if constexpr (::beman::execution::detail::awaitable_sender<Expr, Promise>) {
return ::beman::execution::detail::sender_awaitable<Expr, Promise>{::std::forward<Expr>(expr),
promise};
} else {
return ::std::forward<Expr>(expr);
}
} else {
return ::beman::execution::detail::sender_awaitable<Expr, Promise>{::std::forward<Expr>(expr), promise};
return ::std::forward<Expr>(expr);
}
}
};
Expand Down
38 changes: 38 additions & 0 deletions include/beman/execution/detail/get_await_completion_adaptor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// include/beman/execution/detail/get_await_completion_adaptor.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef INCLUDED_BEMAN_EXECUTION_DETAIL_GET_AWAIT_COMPLETION_ADAPTOR
#define INCLUDED_BEMAN_EXECUTION_DETAIL_GET_AWAIT_COMPLETION_ADAPTOR

#include <beman/execution/detail/common.hpp>
#ifdef BEMAN_HAS_IMPORT_STD
import std;
#else
#include <utility>
#endif
#ifdef BEMAN_HAS_MODULES
import beman.execution.detail.forwarding_query;
#else
#include <beman/execution/detail/forwarding_query.hpp>
#endif

// ----------------------------------------------------------------------------

namespace beman::execution {
struct get_await_completion_adaptor_t {
template <typename Env>
requires requires(Env&& env, const get_await_completion_adaptor_t& g) {
{ ::std::as_const(env).query(g) } noexcept;
}
auto operator()(Env&& env) const noexcept {
return ::std::as_const(env).query(*this);
}
static constexpr auto query(const ::beman::execution::forwarding_query_t&) noexcept -> bool { return true; }
};

inline constexpr get_await_completion_adaptor_t get_await_completion_adaptor{};
} // namespace beman::execution

// ----------------------------------------------------------------------------

#endif // INCLUDED_BEMAN_EXECUTION_DETAIL_GET_AWAIT_COMPLETION_ADAPTOR
10 changes: 6 additions & 4 deletions include/beman/execution/detail/has_completions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import beman.execution.detail.valid_completion_for;
// ----------------------------------------------------------------------------

namespace beman::execution::detail {

template <typename Receiver, ::beman::execution::detail::valid_completion_for<Receiver>... Signatures>
auto has_completions_test(::beman::execution::completion_signatures<Signatures...>*) noexcept -> void {}

template <typename Receiver, typename Completions>
concept has_completions = requires(Completions* completions) {
[]<::beman::execution::detail::valid_completion_for<Receiver>... Signatures>(
::beman::execution::completion_signatures<Signatures...>*) {}(completions);
};
concept has_completions =
requires(Completions* completions) { ::beman::execution::detail::has_completions_test<Receiver>(completions); };
} // namespace beman::execution::detail

// ----------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/beman/execution/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ target_sources(
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/fwd_env.hpp
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/gather_signatures.hpp
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_allocator.hpp
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_await_completion_adaptor.hpp
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_awaiter.hpp
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_completion_scheduler.hpp
${PROJECT_SOURCE_DIR}/include/beman/execution/detail/get_completion_signatures.hpp
Expand Down Expand Up @@ -259,6 +260,7 @@ if(BEMAN_USE_MODULES)
fwd_env.cppm
gather_signatures.cppm
get_allocator.cppm
get_await_completion_adaptor.cppm
get_awaiter.cppm
get_completion_scheduler.cppm
get_completion_signatures.cppm
Expand Down
12 changes: 12 additions & 0 deletions src/beman/execution/get_await_completion_adaptor.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module;
// src/beman/execution/get_await_completion_adaptor.cppm -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/execution/detail/get_await_completion_adaptor.hpp>

export module beman.execution.detail.get_await_completion_adaptor;

namespace beman::execution {
export using beman::execution::get_await_completion_adaptor_t;
export using beman::execution::get_await_completion_adaptor;
} // namespace beman::execution
Loading