Skip to content
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

Add on algorithm #110

Merged
merged 5 commits into from
Jan 4, 2025
Merged
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
6 changes: 3 additions & 3 deletions include/beman/execution26/detail/basic_sender.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ struct basic_sender : ::beman::execution26::detail::product_type<Tag, Data, Chil
return {::std::forward<Self>(self), ::std::move(receiver)};
}
#endif
#if __cpp_explicit_this_parameter < 202110L
#if __cpp_explicit_this_parameter < 302110L
template <typename Env>
auto
get_completion_signatures(Env&&) && -> ::beman::execution26::detail::completion_signatures_for<basic_sender, Env> {
return {};
}
template <typename Env>
auto get_completion_signatures(
Env&&) const&& -> ::beman::execution26::detail::completion_signatures_for<basic_sender, Env> {
Env&&) const&& -> ::beman::execution26::detail::completion_signatures_for<const basic_sender, Env> {
return {};
}
template <typename Env>
Expand All @@ -92,7 +92,7 @@ struct basic_sender : ::beman::execution26::detail::product_type<Tag, Data, Chil
}
template <typename Env>
auto get_completion_signatures(
Env&&) const& -> ::beman::execution26::detail::completion_signatures_for<basic_sender, Env> {
Env&&) const& -> ::beman::execution26::detail::completion_signatures_for<const basic_sender, Env> {
return {};
}
#else
Expand Down
4 changes: 3 additions & 1 deletion include/beman/execution26/detail/connect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ namespace beman::execution26::detail {
struct connect_t {
private:
template <typename Sender, typename Receiver>
static auto make_new_sender(Sender&& sender, Receiver&& receiver) noexcept(true) -> decltype(auto) {
static auto make_new_sender(Sender&& sender, Receiver&& receiver)
//-dk:TODO this noexcept needs to get confirmed/fixed
noexcept(true) -> decltype(auto) {
return ::beman::execution26::transform_sender(
decltype(::beman::execution26::detail::get_domain_late(::std::forward<Sender>(sender),
::beman::execution26::get_env(receiver))){},
Expand Down
169 changes: 169 additions & 0 deletions include/beman/execution26/detail/on.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// include/beman/execution26/detail/on.hpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef INCLUDED_INCLUDE_BEMAN_EXECUTION26_DETAIL_ON
#define INCLUDED_INCLUDE_BEMAN_EXECUTION26_DETAIL_ON

#include <beman/execution26/detail/scheduler.hpp>
#include <beman/execution26/detail/sender.hpp>
#include <beman/execution26/detail/sender_adaptor_closure.hpp>
#include <beman/execution26/detail/transform_sender.hpp>
#include <beman/execution26/detail/query_with_default.hpp>
#include <beman/execution26/detail/get_domain.hpp>
#include <beman/execution26/detail/get_domain_early.hpp>
#include <beman/execution26/detail/default_domain.hpp>
#include <beman/execution26/detail/make_sender.hpp>
#include <beman/execution26/detail/product_type.hpp>
#include <beman/execution26/detail/sender_for.hpp>
#include <beman/execution26/detail/join_env.hpp>
#include <beman/execution26/detail/forward_like.hpp>
#include <beman/execution26/detail/fwd_env.hpp>
#include <beman/execution26/detail/sched_env.hpp>
#include <beman/execution26/detail/starts_on.hpp>
#include <beman/execution26/detail/continues_on.hpp>
#include <beman/execution26/detail/write_env.hpp>
#include <utility>

#include <beman/execution26/detail/suppress_push.hpp>

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

namespace beman::execution26::detail {
struct on_t : ::beman::execution26::sender_adaptor_closure<on_t> {
template <::beman::execution26::detail::sender_for<on_t> OutSndr, typename Env>
auto transform_env(OutSndr&& out_sndr, Env&& env) const -> decltype(auto) {
auto&& data{out_sndr.template get<1>()};

if constexpr (::beman::execution26::scheduler<decltype(data)>)
return ::beman::execution26::detail::join_env(
::beman::execution26::detail::sched_env(::beman::execution26::detail::forward_like<OutSndr>(data)

),
::beman::execution26::detail::fwd_env(::std::forward<Env>(env)));
else
return std::forward<Env>(env);
}

template <typename>
struct env_needs_get_scheduler {
using sender_concept = ::beman::execution26::sender_t;
template <typename Env>
auto get_completion_signatures(Env&&) const {
return env_needs_get_scheduler<Env>{};
}
};

template <::beman::execution26::detail::sender_for<on_t> OutSndr, typename Env>
auto transform_sender(OutSndr&& out_sndr, Env&& env) const -> decltype(auto) {
struct not_a_scheduler {};
auto&& [_, data, child] = out_sndr;

if constexpr (::beman::execution26::scheduler<decltype(data)>) {
auto sch{::beman::execution26::detail::query_with_default(
::beman::execution26::get_scheduler, env, not_a_scheduler{})};
if constexpr (::std::same_as<not_a_scheduler, decltype(sch)>) {
return env_needs_get_scheduler<Env>{};
} else {
return ::beman::execution26::continues_on(
::beman::execution26::starts_on(::beman::execution26::detail::forward_like<OutSndr>(data),
::beman::execution26::detail::forward_like<OutSndr>(child)),
::std::move(sch));
}
} else {
auto& [sch, closure] = data;
auto orig_sch{::beman::execution26::detail::query_with_default(
::beman::execution26::get_completion_scheduler<::beman::execution26::set_value_t>,
::beman::execution26::get_env(child),
::beman::execution26::detail::query_with_default(
::beman::execution26::get_scheduler, env, not_a_scheduler{}))};

if constexpr (::std::same_as<not_a_scheduler, decltype(orig_sch)>) {
return env_needs_get_scheduler<Env>{};
} else {
return ::beman::execution26::detail::write_env(
::beman::execution26::continues_on(
::beman::execution26::detail::forward_like<OutSndr>(closure)(
::beman::execution26::continues_on(
::beman::execution26::detail::write_env(
::beman::execution26::detail::forward_like<OutSndr>(child),
::beman::execution26::detail::sched_env(orig_sch)),
sch)),
orig_sch),
::beman::execution26::detail::sched_env(env));
}
}
}

template <::beman::execution26::scheduler Sch, ::beman::execution26::sender Sndr>
requires ::beman::execution26::detail::is_sender_adaptor_closure<Sndr>
auto operator()(Sch&&, Sndr&&) const -> void =
BEMAN_EXECUTION26_DELETE("on(sch, sndr) requires that sndr isn't both a sender and sender adaptor closure");

template <::beman::execution26::scheduler Sch,
::beman::execution26::sender Sndr,
::beman::execution26::detail::is_sender_adaptor_closure Closure>
requires ::beman::execution26::detail::is_sender_adaptor_closure<Sndr>
auto operator()(Sndr&&, Sch&&, Closure&&) const -> void =
BEMAN_EXECUTION26_DELETE("on(sch, sndr) requires that sndr isn't both a sender and sender adaptor closure");

template <::beman::execution26::scheduler Sch, ::beman::execution26::sender Sndr>
auto operator()(Sch&& sch, Sndr&& sndr) const {
auto domain{::beman::execution26::detail::query_with_default(
::beman::execution26::get_domain, sch, ::beman::execution26::default_domain{})};
return ::beman::execution26::transform_sender(
domain,
::beman::execution26::detail::make_sender(*this, ::std::forward<Sch>(sch), ::std::forward<Sndr>(sndr)));
}
template <::beman::execution26::scheduler Sch,
::beman::execution26::sender Sndr,
::beman::execution26::detail::is_sender_adaptor_closure Closure>
auto operator()(Sndr&& sndr, Sch&& sch, Closure&& closure) const {
auto domain{::beman::execution26::detail::get_domain_early(sndr)};
return ::beman::execution26::transform_sender(
domain,
::beman::execution26::detail::make_sender(
*this,
::beman::execution26::detail::product_type{::std::forward<Sch>(sch), ::std::forward<Closure>(closure)},
::std::forward<Sndr>(sndr)));
}
template <::beman::execution26::scheduler Sch, ::beman::execution26::detail::is_sender_adaptor_closure Closure>
auto operator()(Sch&& sch, Closure&& closure) const {
return ::beman::execution26::detail::sender_adaptor{
*this, ::std::forward<Sch>(sch), ::std::forward<Closure>(closure)};
}
};

#if 0
template <typename Data, typename Sender, typename Env>
struct completion_signatures_for_impl<
::beman::execution26::detail::basic_sender<::beman::execution26::detail::on_t, Data, Sender>,
Env> {
//-dk:TODO pick up scheduler errors and merge them in?
using type =
#if 0
::beman::execution26::detail::meta::combine<
::beman::execution26::completion_signatures_of_t<Sender, Env>,
::beman::execution26::completion_signatures<::beman::execution26::set_error_t(::std::exception_ptr)>
>
#else
::beman::execution26::completion_signatures<
::beman::execution26::set_value_t(),
::beman::execution26::set_error_t(::std::exception_ptr)
>
#endif
;
};
#endif

} // namespace beman::execution26::detail

namespace beman::execution26 {
using on_t = ::beman::execution26::detail::on_t;
inline constexpr ::beman::execution26::on_t on{};
} // namespace beman::execution26

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

#include <beman/execution26/detail/suppress_pop.hpp>

#endif
22 changes: 14 additions & 8 deletions include/beman/execution26/detail/product_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
// ----------------------------------------------------------------------------

namespace beman::execution26::detail {
template <::std::size_t, typename T>

template <::std::size_t I, typename T>
struct product_type_element {
T value;
auto operator==(const product_type_element&) const -> bool = default;
Expand All @@ -23,6 +24,7 @@ template <::std::size_t... I, typename... T>
struct product_type_base<::std::index_sequence<I...>, T...>
: ::beman::execution26::detail::product_type_element<I, T>... {
static constexpr ::std::size_t size() { return sizeof...(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& {
Expand Down Expand Up @@ -64,6 +66,9 @@ struct product_type_base<::std::index_sequence<I...>, T...>
auto operator==(const product_type_base&) const -> bool = default;
};

template <typename T>
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>
Expand Down Expand Up @@ -108,13 +113,14 @@ constexpr auto is_product_type(const ::beman::execution26::detail::product_type<
} // namespace beman::execution26::detail

namespace std {
template <typename... T>
struct tuple_size<::beman::execution26::detail::product_type<T...>>
: ::std::integral_constant<std::size_t, sizeof...(T)> {};
template <::std::size_t I, typename... T>
struct tuple_element<I, ::beman::execution26::detail::product_type<T...>> {
using type =
::std::decay_t<decltype(::std::declval<::beman::execution26::detail::product_type<T...>>().template get<I>())>;
template <typename T>
requires ::beman::execution26::detail::is_product_type_c<T>
struct tuple_size<T> : ::std::integral_constant<std::size_t, T::size()> {};

template <::std::size_t I, typename T>
requires ::beman::execution26::detail::is_product_type_c<T>
struct tuple_element<I, T> {
using type = ::std::decay_t<decltype(::std::declval<T>().template get<I>())>;
};
} // namespace std

Expand Down
26 changes: 20 additions & 6 deletions include/beman/execution26/detail/schedule_from.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
#define INCLUDED_BEMAN_EXECUTION26_DETAIL_SCHEDULE_FROM

#include <beman/execution26/detail/child_type.hpp>
#include <beman/execution26/detail/meta_combine.hpp>
#include <beman/execution26/detail/completion_signatures_of_t.hpp>
#include <beman/execution26/detail/connect.hpp>
#include <beman/execution26/detail/decayed_tuple.hpp>
#include <beman/execution26/detail/default_domain.hpp>
#include <beman/execution26/detail/default_impls.hpp>
#include <beman/execution26/detail/error_types_of_t.hpp>
#include <beman/execution26/detail/env_of_t.hpp>
#include <beman/execution26/detail/fwd_env.hpp>
#include <beman/execution26/detail/get_domain.hpp>
Expand Down Expand Up @@ -144,10 +146,15 @@ struct impls_for<::beman::execution26::detail::schedule_from_t> : ::beman::execu
::std::monostate,
::beman::execution26::detail::meta::transform<
::beman::execution26::detail::as_tuple_t,
::beman::execution26::detail::meta::to<::std::variant,
::beman::execution26::completion_signatures_of_t<
::beman::execution26::detail::child_type<Sender>,
::beman::execution26::env_of_t<Receiver>>>>>>;
::beman::execution26::detail::meta::to<
::std::variant,
::beman::execution26::detail::meta::combine<
::beman::execution26::completion_signatures_of_t<
::beman::execution26::detail::child_type<Sender>,
::beman::execution26::env_of_t<Receiver>>,
//-dk:TODO get proper error completion signatures
::beman::execution26::completion_signatures<::beman::execution26::set_error_t(
::std::exception_ptr)>>>>>>;

return state_type<Receiver, sched_t, variant_t>(sch, receiver);
}};
Expand Down Expand Up @@ -176,8 +183,15 @@ template <typename Scheduler, typename Sender, typename Env>
struct completion_signatures_for_impl<
::beman::execution26::detail::basic_sender<::beman::execution26::detail::schedule_from_t, Scheduler, Sender>,
Env> {
using type =
decltype(::beman::execution26::get_completion_signatures(::std::declval<Sender>(), ::std::declval<Env>()));
using scheduler_sender = decltype(::beman::execution26::schedule(::std::declval<Scheduler>()));
template <typename... E>
using as_set_error = ::beman::execution26::completion_signatures<::beman::execution26::set_error_t(E)...>;
using type = ::beman::execution26::detail::meta::combine<
decltype(::beman::execution26::get_completion_signatures(::std::declval<Sender>(), ::std::declval<Env>())),
::beman::execution26::error_types_of_t<scheduler_sender, Env, as_set_error>,
::beman::execution26::completion_signatures<::beman::execution26::set_error_t(
::std::exception_ptr)> //-dk:TODO this one should be deduced
>;
};
} // namespace beman::execution26::detail

Expand Down
8 changes: 8 additions & 0 deletions include/beman/execution26/detail/sender_adaptor_closure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,16 @@ namespace beman::execution26 {
template <typename>
struct sender_adaptor_closure : ::beman::execution26::detail::pipeable::sender_adaptor_closure_base {};
// NOLINTEND(bugprone-crtp-constructor-accessibility)

} // namespace beman::execution26

namespace beman::execution26::detail {
template <typename Closure>
concept is_sender_adaptor_closure =
::std::derived_from<::std::decay_t<Closure>,
::beman::execution26::sender_adaptor_closure<::std::decay_t<Closure>>>;
}

namespace beman::execution26::detail::pipeable {
template <::beman::execution26::sender Sender, typename Adaptor>
requires(not::beman::execution26::sender<Adaptor>) &&
Expand Down
Loading
Loading