-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get completion behaviour #115
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// 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 { | ||
new_sender(::std::forward<Sender>(sender), ::std::forward<Env>(env)) | ||
.get_completion_behaviour(std::forward<Env>(env)); | ||
}) { | ||
std::remove_cvref_t<Env> copiedEnv(env); | ||
return new_sender(::std::forward<Sender>(sender), ::std::forward<Env>(copiedEnv)) | ||
.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(::std::forward<Sender>(sender), ::std::forward<Env>(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 |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -29,34 +29,35 @@ struct product_type_base<::std::index_sequence<I...>, T...> | |||||||||
static constexpr bool is_product_type{true}; | ||||||||||
|
||||||||||
template <::std::size_t J, typename S> | ||||||||||
static auto element_get(::beman::execution26::detail::product_type_element<J, S>& self) noexcept -> S& { | ||||||||||
static constexpr auto element_get(::beman::execution26::detail::product_type_element<J, S>& self) noexcept -> S& { | ||||||||||
return self.value; | ||||||||||
} | ||||||||||
template <::std::size_t J, typename S> | ||||||||||
static auto element_get(::beman::execution26::detail::product_type_element<J, S>&& self) noexcept -> S&& { | ||||||||||
static constexpr auto | ||||||||||
element_get(::beman::execution26::detail::product_type_element<J, S>&& self) noexcept -> S&& { | ||||||||||
Comment on lines
+36
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [pre-commit] reported by reviewdog 🐶
Suggested change
|
||||||||||
return ::std::move(self.value); | ||||||||||
} | ||||||||||
template <::std::size_t J, typename S> | ||||||||||
static auto element_get(const ::beman::execution26::detail::product_type_element<J, S>& self) noexcept | ||||||||||
-> const S& { | ||||||||||
static constexpr auto | ||||||||||
element_get(const ::beman::execution26::detail::product_type_element<J, S>& self) noexcept -> const S& { | ||||||||||
Comment on lines
+41
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [pre-commit] reported by reviewdog 🐶
Suggested change
|
||||||||||
return self.value; | ||||||||||
} | ||||||||||
|
||||||||||
template <::std::size_t J> | ||||||||||
auto get() & -> decltype(auto) { | ||||||||||
constexpr auto get() & -> decltype(auto) { | ||||||||||
return this->element_get<J>(*this); | ||||||||||
} | ||||||||||
template <::std::size_t J> | ||||||||||
auto get() && -> decltype(auto) { | ||||||||||
constexpr auto get() && -> decltype(auto) { | ||||||||||
return this->element_get<J>(::std::move(*this)); | ||||||||||
} | ||||||||||
template <::std::size_t J> | ||||||||||
auto get() const& -> decltype(auto) { | ||||||||||
constexpr auto get() const& -> decltype(auto) { | ||||||||||
return this->element_get<J>(*this); | ||||||||||
} | ||||||||||
|
||||||||||
template <::std::size_t J, typename Allocator, typename Self> | ||||||||||
static auto make_element(Allocator&& alloc, Self&& self) -> decltype(auto) { | ||||||||||
static constexpr auto make_element(Allocator&& alloc, Self&& self) -> decltype(auto) { | ||||||||||
using type = ::std::remove_cvref_t<decltype(product_type_base::element_get<J>(std::forward<Self>(self)))>; | ||||||||||
if constexpr (::std::uses_allocator_v<type, Allocator>) | ||||||||||
return ::std::make_obj_using_allocator<type>(alloc, | ||||||||||
|
@@ -65,7 +66,7 @@ struct product_type_base<::std::index_sequence<I...>, T...> | |||||||||
return product_type_base::element_get<J>(std::forward<Self>(self)); | ||||||||||
} | ||||||||||
|
||||||||||
auto operator==(const product_type_base&) const -> bool = default; | ||||||||||
constexpr auto operator==(const product_type_base&) const -> bool = default; | ||||||||||
}; | ||||||||||
|
||||||||||
template <typename T> | ||||||||||
|
@@ -74,12 +75,13 @@ concept is_product_type_c = requires(const T& t) { T::is_product_type; }; | |||||||||
template <typename... T> | ||||||||||
struct product_type : ::beman::execution26::detail::product_type_base<::std::index_sequence_for<T...>, T...> { | ||||||||||
template <typename Allocator, typename Product, std::size_t... I> | ||||||||||
static auto make_from(Allocator&& allocator, Product&& product, std::index_sequence<I...>) -> product_type { | ||||||||||
static constexpr auto | ||||||||||
make_from(Allocator&& allocator, Product&& product, std::index_sequence<I...>) -> product_type { | ||||||||||
Comment on lines
+78
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [pre-commit] reported by reviewdog 🐶
Suggested change
|
||||||||||
return {product_type::template make_element<I>(allocator, ::std::forward<Product>(product))...}; | ||||||||||
} | ||||||||||
|
||||||||||
template <typename Allocator, typename Product> | ||||||||||
static auto make_from(Allocator&& allocator, Product&& product) -> product_type { | ||||||||||
static constexpr auto make_from(Allocator&& allocator, Product&& product) -> product_type { | ||||||||||
return product_type::make_from( | ||||||||||
::std::forward<Allocator>(allocator), ::std::forward<Product>(product), ::std::index_sequence_for<T...>{}); | ||||||||||
} | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[pre-commit] reported by reviewdog 🐶