-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: initial implementation of D3206R0
- Loading branch information
Showing
8 changed files
with
174 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// include/beman/execution26/detail/completion_behaviour.hpp -*-C++-*- | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_COMPLETION_BEHAVIOUR | ||
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_COMPLETION_BEHAVIOUR | ||
|
||
#include <cstdint> | ||
|
||
namespace beman::execution26 { | ||
enum class completion_behaviour : std::uint8_t { inline_completion, synchronous, asynchronous, unknown }; | ||
} // namespace beman::execution26 | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
include/beman/execution26/detail/get_completion_behaviour.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// include/beman/execution26/detail/get_completion_behaviour.hpp -*-C++-*- | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_GET_COMPLETION_BEHAVIOUR | ||
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_GET_COMPLETION_BEHAVIOUR | ||
|
||
#include <beman/execution26/detail/completion_behaviour.hpp> | ||
#include <beman/execution26/detail/forward_like.hpp> | ||
#include <beman/execution26/detail/is_awaitable.hpp> | ||
#include <beman/execution26/detail/get_domain_late.hpp> | ||
#include <beman/execution26/detail/transform_sender.hpp> | ||
|
||
#include <type_traits> | ||
|
||
namespace beman::execution26 { | ||
|
||
struct get_completion_behaviour_t { | ||
template <class Sender> | ||
constexpr auto operator()(Sender&& sender) const noexcept { | ||
if constexpr (requires { typename ::std::remove_cvref_t<Sender>::completion_behaviour; }) { | ||
return typename ::std::remove_cvref_t<Sender>::completion_behaviour{}; | ||
} else if constexpr (requires { ::std::forward<Sender>(sender).get_completion_behaviour(); }) { | ||
return ::std::forward<Sender>(sender).get_completion_behaviour(); | ||
} else if constexpr (::beman::execution26::detail::is_awaitable< | ||
::std::remove_cvref_t<Sender>, | ||
::beman::execution26::detail::env_promise<::beman::execution26::empty_env>>) { | ||
return sender.await_ready() ? ::beman::execution26::completion_behaviour::inline_completion | ||
: ::beman::execution26::completion_behaviour::unknown; | ||
} else { | ||
return ::beman::execution26::completion_behaviour::unknown; | ||
} | ||
} | ||
|
||
template <class Sender, class Env> | ||
constexpr auto operator()(Sender&& sender, Env&& env) const noexcept { | ||
auto new_sender{[](auto&& sndr, auto&& e) -> decltype(auto) { | ||
auto domain{::beman::execution26::detail::get_domain_late(sndr, e)}; | ||
return ::beman::execution26::transform_sender( | ||
domain, ::std::forward<Sender>(sndr), ::std::forward<Env>(e)); | ||
}}; | ||
|
||
using new_sender_type = | ||
::std::remove_cvref_t<decltype(new_sender(::std::forward<Sender>(sender), ::std::forward<Env>(env)))>; | ||
using decayed_env = ::std::remove_cvref_t<Env>; | ||
|
||
if constexpr (requires { typename new_sender_type::completion_behaviour; }) { | ||
return typename new_sender_type::completion_behaviour{}; | ||
} else if constexpr (requires { ::std::move(new_sender).get_completion_behaviour(std::forward<Env>(env)); }) { | ||
return std::move(new_sender).get_completion_behaviour(std::forward<Env>(env)); | ||
} else if constexpr (::beman::execution26::detail::is_awaitable< | ||
new_sender_type, | ||
::beman::execution26::detail::env_promise<decayed_env>>) { | ||
if (new_sender(sender, env).await_ready()) { | ||
return completion_behaviour::inline_completion; | ||
} else { | ||
return completion_behaviour::unknown; | ||
} | ||
} else { | ||
return completion_behaviour::unknown; | ||
} | ||
} | ||
}; | ||
|
||
inline constexpr get_completion_behaviour_t get_completion_behaviour{}; | ||
|
||
} // namespace beman::execution26 | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
tests/beman/execution26/exec-get-completion-behaviour.test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// src/beman/execution26/tests/exec-get-completion-behaviour.test.cpp -*-C++-*- | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include <beman/execution26/detail/get_completion_behaviour.hpp> | ||
|
||
#include <test/execution.hpp> | ||
|
||
#include <type_traits> | ||
|
||
namespace { | ||
|
||
template <auto Value> | ||
using value = std::integral_constant<decltype(Value), Value>; | ||
|
||
struct awaitable { | ||
static constexpr auto await_ready() noexcept -> bool { return true; } | ||
auto await_suspend(auto parent) noexcept { return parent; } | ||
auto await_resume() noexcept -> void {} | ||
}; | ||
|
||
void test_constexpr_awaitable() { | ||
auto completion_behaviour = value<test_std::get_completion_behaviour(awaitable{})>{}; | ||
ASSERT(test_std::completion_behaviour::inline_completion == completion_behaviour); | ||
} | ||
struct sender { | ||
using completion_behaviour = value<test_std::completion_behaviour::inline_completion>; | ||
}; | ||
|
||
struct sender2 { | ||
static constexpr auto get_completion_behaviour() noexcept -> test_std::completion_behaviour { | ||
return test_std::completion_behaviour::inline_completion; | ||
} | ||
}; | ||
|
||
void test_typedef_sender() { | ||
auto completion_behaviour = | ||
std::integral_constant<test_std::completion_behaviour, test_std::get_completion_behaviour(sender{})>{}; | ||
ASSERT(test_std::completion_behaviour::inline_completion == completion_behaviour); | ||
} | ||
|
||
void test_constexpr_sender() { | ||
auto completion_behaviour = | ||
std::integral_constant<test_std::completion_behaviour, test_std::get_completion_behaviour(sender{})>{}; | ||
ASSERT(test_std::completion_behaviour::inline_completion == completion_behaviour); | ||
} | ||
|
||
} // namespace | ||
|
||
TEST(exec_get_completion_behaviour) { | ||
test_constexpr_awaitable(); | ||
test_typedef_sender(); | ||
test_constexpr_sender(); | ||
} |