Skip to content

Commit 5473e9d

Browse files
committed
refactor __receiver_ref
1 parent f0c6f54 commit 5473e9d

3 files changed

Lines changed: 27 additions & 75 deletions

File tree

include/exec/fork_join.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ namespace experimental::execution
147147
using _when_all_sndr_t =
148148
fork_join_impl_t::_when_all_sndr_t<_child_completions_t, Closures, _domain_t>;
149149
using _child_opstate_t =
150-
STDEXEC::connect_result_t<Sndr, STDEXEC::__rcvr_ref_t<_opstate_t, _env_t>>;
150+
STDEXEC::connect_result_t<Sndr, STDEXEC::__receiver_ref<_opstate_t, _env_t>>;
151151
using _fork_opstate_t =
152-
STDEXEC::connect_result_t<_when_all_sndr_t, STDEXEC::__rcvr_ref_t<Rcvr>>;
152+
STDEXEC::connect_result_t<_when_all_sndr_t, STDEXEC::__receiver_ref<Rcvr>>;
153153
using _cache_sndr_t =
154154
fork_join_impl_t::_cache_sndr_t<_variant_t<_child_completions_t>, _domain_t>;
155155

@@ -159,11 +159,11 @@ namespace experimental::execution
159159
, _fork_opstate_(STDEXEC::connect(STDEXEC::__apply(_mk_when_all_fn{},
160160
static_cast<Closures&&>(closures),
161161
_cache_sndr_t{&_cache_}),
162-
STDEXEC::__ref_rcvr(_rcvr_)))
162+
STDEXEC::__receiver_ref(_rcvr_)))
163163
{
164164
_child_opstate_.__construct_from(STDEXEC::connect,
165165
static_cast<Sndr&&>(sndr),
166-
STDEXEC::__ref_rcvr(*this));
166+
STDEXEC::__receiver_ref(*this));
167167
}
168168

169169
STDEXEC_IMMOVABLE(_opstate_t);

include/exec/unless_stop_requested.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ namespace experimental::execution
4646
struct __opstate
4747
{
4848
using receiver_concept = receiver_t;
49-
using __child_op_t = connect_result_t<_CvChild, __rcvr_ref_t<_Receiver>>;
49+
using __child_op_t = connect_result_t<_CvChild, __receiver_ref<_Receiver>>;
5050

5151
constexpr explicit __opstate(_CvChild&& __child, _Receiver __rcvr)
52-
noexcept(__nothrow_connectable<_CvChild, __rcvr_ref_t<_Receiver>>)
52+
noexcept(__nothrow_connectable<_CvChild, __receiver_ref<_Receiver>>)
5353
: __rcvr_(static_cast<_Receiver&&>(__rcvr))
5454
, __child_op_(
55-
STDEXEC::connect(static_cast<_CvChild&&>(__child), STDEXEC::__ref_rcvr(__rcvr_)))
55+
STDEXEC::connect(static_cast<_CvChild&&>(__child), STDEXEC::__receiver_ref(__rcvr_)))
5656
{}
5757

5858
constexpr void start() noexcept
@@ -99,7 +99,7 @@ namespace experimental::execution
9999

100100
template <class _Receiver>
101101
using __rcvr_t =
102-
__if_c<__unstoppable_receiver<_Receiver>, _Receiver, __rcvr_ref_t<_Receiver>>;
102+
__if_c<__unstoppable_receiver<_Receiver>, _Receiver, __receiver_ref<_Receiver>>;
103103

104104
static constexpr auto __connect = //
105105
[]<class _Sender, class _Receiver>(_Sender&& __sndr, _Receiver __rcvr) noexcept(

include/stdexec/__detail/__receiver_ref.hpp

Lines changed: 19 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -22,106 +22,58 @@
2222
#include "__receivers.hpp"
2323

2424
#include <memory>
25+
#include <utility>
2526

2627
namespace STDEXEC
2728
{
28-
template <class _Rcvr, class _Env = env_of_t<_Rcvr>>
29-
struct __rcvr_ref
29+
template <class _RcvrPtr, class _Env = env_of_t<decltype(*_RcvrPtr())>>
30+
struct __pointer_receiver
3031
{
3132
using receiver_concept = receiver_t;
3233

3334
STDEXEC_ATTRIBUTE(host, device)
34-
constexpr explicit __rcvr_ref(_Rcvr& __rcvr) noexcept
35-
: __rcvr_{std::addressof(__rcvr)}
35+
constexpr explicit __pointer_receiver(_RcvrPtr __rcvr_ptr) noexcept
36+
: __rcvr_ptr_{__rcvr_ptr}
3637
{}
3738

3839
template <class... _As>
3940
STDEXEC_ATTRIBUTE(host, device)
4041
constexpr void set_value(_As&&... __as) noexcept
4142
{
42-
STDEXEC::set_value(static_cast<_Rcvr&&>(*__rcvr_), static_cast<_As&&>(__as)...);
43+
STDEXEC::set_value(std::move(*__rcvr_ptr_), static_cast<_As&&>(__as)...);
4344
}
4445

4546
template <class _Error>
4647
STDEXEC_ATTRIBUTE(host, device)
4748
constexpr void set_error(_Error&& __err) noexcept
4849
{
49-
STDEXEC::set_error(static_cast<_Rcvr&&>(*__rcvr_), static_cast<_Error&&>(__err));
50+
STDEXEC::set_error(std::move(*__rcvr_ptr_), static_cast<_Error&&>(__err));
5051
}
5152

52-
STDEXEC_ATTRIBUTE(host, device) constexpr void set_stopped() noexcept
53+
STDEXEC_ATTRIBUTE(host, device)
54+
constexpr void set_stopped() noexcept
5355
{
54-
STDEXEC::set_stopped(static_cast<_Rcvr&&>(*__rcvr_));
56+
STDEXEC::set_stopped(std::move(*__rcvr_ptr_));
5557
}
5658

5759
STDEXEC_ATTRIBUTE(nodiscard, host, device)
5860
constexpr auto get_env() const noexcept -> _Env
5961
{
60-
static_assert(__same_as<_Env, env_of_t<_Rcvr>>,
62+
static_assert(__same_as<_Env, env_of_t<decltype(*_RcvrPtr())>>,
6163
"get_env() must return the same type as env_of_t<_Rcvr>");
62-
return STDEXEC::get_env(*__rcvr_);
64+
return STDEXEC::get_env(*__rcvr_ptr_);
6365
}
6466

6567
private:
66-
_Rcvr* __rcvr_;
68+
_RcvrPtr __rcvr_ptr_;
6769
};
6870

69-
namespace __detail
71+
template <class _Rcvr, class _Env = env_of_t<_Rcvr>>
72+
struct __receiver_ref : __pointer_receiver<_Rcvr*, _Env>
7073
{
71-
template <class _Rcvr, size_t = sizeof(_Rcvr)>
72-
STDEXEC_ATTRIBUTE(host, device)
73-
constexpr auto __is_type_complete(int) noexcept
74-
{
75-
return true;
76-
}
77-
78-
template <class _Rcvr>
7974
STDEXEC_ATTRIBUTE(host, device)
80-
constexpr auto __is_type_complete(long) noexcept
81-
{
82-
return false;
83-
}
84-
} // namespace __detail
85-
86-
// The __ref_rcvr function and its helpers are used to avoid wrapping a receiver in a
87-
// __rcvr_ref when that is possible. The logic goes as follows:
88-
89-
// 1. If the receiver is an instance of __rcvr_ref, return it.
90-
// 2. If the type is incomplete or an operation state, return a __rcvr_ref wrapping the
91-
// receiver.
92-
// 3. If the receiver is nothrow copy constructible, return it.
93-
// 4. Otherwise, return a __rcvr_ref wrapping the receiver.
94-
template <class _Env = void, class _Rcvr>
95-
STDEXEC_ATTRIBUTE(nodiscard, host, device)
96-
constexpr auto __ref_rcvr(_Rcvr& __rcvr) noexcept
97-
{
98-
if constexpr (__same_as<_Env, void>)
99-
{
100-
return STDEXEC::__ref_rcvr<env_of_t<_Rcvr>>(__rcvr);
101-
}
102-
else if constexpr (__is_instance_of<_Rcvr, __rcvr_ref>)
103-
{
104-
return __rcvr;
105-
}
106-
else if constexpr (!__detail::__is_type_complete<_Rcvr>(0))
107-
{
108-
return __rcvr_ref<_Rcvr, _Env>{__rcvr};
109-
}
110-
else if constexpr (operation_state<_Rcvr>)
111-
{
112-
return __rcvr_ref<_Rcvr, _Env>{__rcvr};
113-
}
114-
else if constexpr (__nothrow_constructible_from<_Rcvr, _Rcvr const &>)
115-
{
116-
return const_cast<_Rcvr const &>(__rcvr);
117-
}
118-
else
119-
{
120-
return __rcvr_ref{__rcvr};
121-
}
122-
STDEXEC_UNREACHABLE();
123-
}
124-
125-
template <class _Rcvr, class _Env = env_of_t<_Rcvr>>
126-
using __rcvr_ref_t = decltype(STDEXEC::__ref_rcvr<_Env>(STDEXEC::__declval<_Rcvr&>()));
75+
constexpr __receiver_ref(_Rcvr& __rcvr) noexcept
76+
: __pointer_receiver<_Rcvr*, _Env>(std::addressof(__rcvr))
77+
{}
78+
};
12779
} // namespace STDEXEC

0 commit comments

Comments
 (0)