Skip to content

Commit

Permalink
make unstoppable() a concrete type
Browse files Browse the repository at this point in the history
- allows for customizations via tag_invoke
  • Loading branch information
janondrusek committed Mar 29, 2023
1 parent 7977ad7 commit d6e3ef3
Showing 1 changed file with 53 additions and 5 deletions.
58 changes: 53 additions & 5 deletions include/unifex/unstoppable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,64 @@

namespace unifex {
namespace _unstoppable {

template <typename Sender>
struct _sender final {
struct type;
};

template <typename Sender>
using sender = typename _sender<remove_cvref_t<Sender>>::type;

template <typename Sender>
struct _sender<Sender>::type final {
UNIFEX_NO_UNIQUE_ADDRESS Sender sender_;

template <
template <typename...>
class Variant,
template <typename...>
class Tuple>
using value_types = sender_value_types_t<Sender, Variant, Tuple>;

template <template <typename...> class Variant>
using error_types = sender_error_types_t<Sender, Variant>;

static constexpr bool sends_done = sender_traits<Sender>::sends_done;

template(typename Self, typename Receiver) //
(requires same_as<type, remove_cvref_t<Self>> AND
sender_to<member_t<Self, Sender>, Receiver>) //
friend auto tag_invoke(tag_t<connect>, Self&& self, Receiver&& r) noexcept(
is_nothrow_connectable_v<
member_t<Self, Sender>,
remove_cvref_t<Receiver>>) {
return connect(
with_query_value(
static_cast<Self&&>(self).sender_,
get_stop_token,
unstoppable_token{}),
static_cast<Receiver&&>(r));
}

friend auto tag_invoke(tag_t<blocking>, const type& s) noexcept {
return blocking(s.sender_);
}
};

} // namespace _unstoppable

namespace _unstoppable_cpo {
inline const struct _fn {
template <typename Sender>
constexpr auto operator()(Sender&& sender) const noexcept {
return with_query_value(
(Sender &&) sender, get_stop_token, unstoppable_token{});
constexpr auto operator()(Sender&& sender) const noexcept(
std::is_nothrow_constructible_v<_unstoppable::sender<Sender>, Sender>) {
return _unstoppable::sender<Sender>{static_cast<Sender&&>(sender)};
}
} unstoppable{};
} // namespace _unstoppable
} // namespace _unstoppable_cpo

using _unstoppable::unstoppable;
using _unstoppable_cpo::unstoppable;

} // namespace unifex

Expand Down

0 comments on commit d6e3ef3

Please sign in to comment.