Skip to content

Commit d6e3ef3

Browse files
committed
make unstoppable() a concrete type
- allows for customizations via tag_invoke
1 parent 7977ad7 commit d6e3ef3

File tree

1 file changed

+53
-5
lines changed

1 file changed

+53
-5
lines changed

include/unifex/unstoppable.hpp

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,64 @@
2222

2323
namespace unifex {
2424
namespace _unstoppable {
25+
26+
template <typename Sender>
27+
struct _sender final {
28+
struct type;
29+
};
30+
31+
template <typename Sender>
32+
using sender = typename _sender<remove_cvref_t<Sender>>::type;
33+
34+
template <typename Sender>
35+
struct _sender<Sender>::type final {
36+
UNIFEX_NO_UNIQUE_ADDRESS Sender sender_;
37+
38+
template <
39+
template <typename...>
40+
class Variant,
41+
template <typename...>
42+
class Tuple>
43+
using value_types = sender_value_types_t<Sender, Variant, Tuple>;
44+
45+
template <template <typename...> class Variant>
46+
using error_types = sender_error_types_t<Sender, Variant>;
47+
48+
static constexpr bool sends_done = sender_traits<Sender>::sends_done;
49+
50+
template(typename Self, typename Receiver) //
51+
(requires same_as<type, remove_cvref_t<Self>> AND
52+
sender_to<member_t<Self, Sender>, Receiver>) //
53+
friend auto tag_invoke(tag_t<connect>, Self&& self, Receiver&& r) noexcept(
54+
is_nothrow_connectable_v<
55+
member_t<Self, Sender>,
56+
remove_cvref_t<Receiver>>) {
57+
return connect(
58+
with_query_value(
59+
static_cast<Self&&>(self).sender_,
60+
get_stop_token,
61+
unstoppable_token{}),
62+
static_cast<Receiver&&>(r));
63+
}
64+
65+
friend auto tag_invoke(tag_t<blocking>, const type& s) noexcept {
66+
return blocking(s.sender_);
67+
}
68+
};
69+
70+
} // namespace _unstoppable
71+
72+
namespace _unstoppable_cpo {
2573
inline const struct _fn {
2674
template <typename Sender>
27-
constexpr auto operator()(Sender&& sender) const noexcept {
28-
return with_query_value(
29-
(Sender &&) sender, get_stop_token, unstoppable_token{});
75+
constexpr auto operator()(Sender&& sender) const noexcept(
76+
std::is_nothrow_constructible_v<_unstoppable::sender<Sender>, Sender>) {
77+
return _unstoppable::sender<Sender>{static_cast<Sender&&>(sender)};
3078
}
3179
} unstoppable{};
32-
} // namespace _unstoppable
80+
} // namespace _unstoppable_cpo
3381

34-
using _unstoppable::unstoppable;
82+
using _unstoppable_cpo::unstoppable;
3583

3684
} // namespace unifex
3785

0 commit comments

Comments
 (0)