Skip to content

Commit 12b667a

Browse files
committed
rewrite any_sender_of in terms of __any
1 parent e789bca commit 12b667a

15 files changed

Lines changed: 1080 additions & 1883 deletions

include/exec/any_sender_of.hpp

Lines changed: 580 additions & 1277 deletions
Large diffs are not rendered by default.

include/exec/at_coroutine_exit.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ namespace experimental::execution
3131
using namespace STDEXEC;
3232

3333
using __any_scheduler_t =
34-
any_receiver_ref<completion_signatures<set_error_t(std::exception_ptr),
34+
any_receiver_ref<completion_signatures<set_value_t(),
35+
set_error_t(std::exception_ptr),
3536
set_stopped_t()>>::any_sender<>::any_scheduler<>;
3637

3738
struct __die_on_stop_t

include/exec/on_coro_disposition.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ namespace experimental::execution
3333
using namespace STDEXEC;
3434

3535
using __any_scheduler =
36-
any_receiver_ref<completion_signatures<set_error_t(std::exception_ptr),
36+
any_receiver_ref<completion_signatures<set_value_t(),
37+
set_error_t(std::exception_ptr),
3738
set_stopped_t()>>::any_sender<>::any_scheduler<>;
3839

3940
template <class _Promise>

include/exec/sequence/any_sequence_of.hpp

Lines changed: 152 additions & 297 deletions
Large diffs are not rendered by default.

include/exec/sequence_senders.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ namespace experimental::execution
140140
noexcept(noexcept(__rcvr.set_next(static_cast<_Item&&>(__item))))
141141
-> decltype(__rcvr.set_next(static_cast<_Item&&>(__item)))
142142
{
143+
static_assert(next_sender<decltype(__rcvr.set_next(static_cast<_Item&&>(__item)))>,
144+
"The sender returned from set_next is required to complete with "
145+
"set_value_t() or set_stopped_t()");
143146
return __rcvr.set_next(static_cast<_Item&&>(__item));
144147
}
145148

@@ -153,8 +156,7 @@ namespace experimental::execution
153156
{
154157
static_assert(next_sender<__tag_invoke_result_t<set_next_t, _Receiver&, _Item>>,
155158
"The sender returned from set_next is required to complete with "
156-
"set_value_t() or "
157-
"set_stopped_t()");
159+
"set_value_t() or set_stopped_t()");
158160
return __tag_invoke(*this, __rcvr, static_cast<_Item&&>(__item));
159161
}
160162
};
@@ -819,8 +821,9 @@ namespace experimental::execution
819821
}
820822
else
821823
{
822-
static_assert(__subscribable_with_static_member<__tfx_seq_t, _Receiver>,
823-
STDEXEC_ERROR_CANNOT_SUBSCRIBE_SEQUENCE_TO_RECEIVER);
824+
using __result_t [[maybe_unused]] = decltype(__declval<__tfx_seq_t>().subscribe(__declval<_Receiver>()));
825+
// static_assert(__subscribable_with_static_member<__tfx_seq_t, _Receiver>,
826+
// STDEXEC_ERROR_CANNOT_SUBSCRIBE_SEQUENCE_TO_RECEIVER);
824827
return _NO_USABLE_SUBSCRIBE_CUSTOMIZATION_FOUND_();
825828
}
826829
}

include/exec/task.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace experimental::execution
4343
// The required set_value_t() scheduler-sender completion signature is added in
4444
// any_receiver_ref::any_sender::any_scheduler.
4545
using __any_scheduler_completions =
46-
completion_signatures<set_error_t(std::exception_ptr), set_stopped_t()>;
46+
completion_signatures<set_value_t(), set_error_t(std::exception_ptr), set_stopped_t()>;
4747

4848
using __any_scheduler =
4949
any_receiver_ref<__any_scheduler_completions>::any_sender<>::any_scheduler<>;

include/stdexec/__detail/__any.hpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,9 @@ namespace STDEXEC::__any
667667
: _Interface<__mcall1<__bases_of<_Interface>, __value_proxy_root<_Interface>>>
668668
{};
669669

670+
template <class _Interface, __root_kind _RootKind>
671+
concept __has_root_kind = std::remove_reference_t<_Interface>::__root_kind == _RootKind;
672+
670673
//////////////////////////////////////////////////////////////////////////////////////////
671674
//! __interface_base
672675
template <template <class> class _Interface,
@@ -693,15 +696,20 @@ namespace STDEXEC::__any
693696
? _BufferAlignment
694697
: _Base::__buffer_alignment;
695698

699+
static constexpr bool __can_slice = __extension_of<_Base, __imovable>
700+
&& (__has_root_kind<_Base, __root_kind::__value>
701+
|| __extension_of<_Base, __icopyable>);
702+
696703
static constexpr bool __nothrow_slice =
697704
STDEXEC::__any::__nothrow_slice<__this_interface_type, _Base, __buffer_size>;
698705

699706
//! @pre !empty(*this)
700-
constexpr virtual void
701-
__slice_to_(__value_proxy_root<_Interface> &__result) noexcept(__nothrow_slice)
707+
constexpr virtual void __slice_to_(__value_proxy_root<_Interface> &__result) //
708+
noexcept(__nothrow_slice)
702709
{
703710
STDEXEC_ASSERT(!__empty(*this));
704-
if constexpr (_Base::__box_kind != __box_kind::__abstract)
711+
STDEXEC_ASSERT(__can_slice);
712+
if constexpr (_Base::__box_kind != __box_kind::__abstract && __can_slice)
705713
{
706714
using __root_interface_t = _Base::__interface_type;
707715
constexpr bool __is_root_interface =
@@ -714,12 +722,15 @@ namespace STDEXEC::__any
714722
__value(*this).__slice_to_(__result);
715723
__reset(*this);
716724
}
717-
else // if constexpr (_Base::__box_kind == __box_kind::__object)
725+
else if constexpr (_Base::__root_kind == __root_kind::__value)
718726
{
719727
// Move from type-erased values, but not from type-erased references
720-
constexpr bool __is_value = (_Base::__root_kind == __root_kind::__value);
721728
// potentially throwing:
722-
__result.emplace(STDEXEC_DECAY_COPY(STDEXEC::__move_if<__is_value>(__value(*this))));
729+
__result.emplace(std::move(__value(*this)));
730+
}
731+
else
732+
{
733+
__result.emplace(__value(*this));
723734
}
724735
}
725736
}

include/stdexec/__detail/__connect.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ namespace STDEXEC
232232
constexpr auto operator()(_Sender&& __sndr, _Receiver&& __rcvr) const
233233
noexcept(__nothrow_callable<_DeclFn>) -> __call_result_t<_DeclFn>
234234
{
235-
auto&& __new_sndr = transform_sender(static_cast<_Sender&&>(__sndr), get_env(__rcvr));
235+
decltype(auto) __new_sndr = transform_sender(static_cast<_Sender&&>(__sndr), get_env(__rcvr));
236236
using __new_sndr_t = decltype(__new_sndr);
237237

238238
if constexpr (__connect::__with_static_member<__new_sndr_t, _Receiver>)

include/stdexec/__detail/__diagnostics.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ namespace STDEXEC
218218

219219
struct dependent_sender_error : __compile_time_error<dependent_sender_error>
220220
{
221+
constexpr dependent_sender_error() noexcept
222+
: what_("This sender needs to know its execution environment before it can know how it will complete.")
223+
{}
224+
221225
constexpr explicit dependent_sender_error(char const *what) noexcept
222226
: what_(what)
223227
{}

include/stdexec/__detail/__meta.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,14 @@ namespace STDEXEC
207207
template <class... _What>
208208
extern _ERROR_<_What...> __ok_v<__mexception<_What...>>;
209209

210+
template <class... _What>
211+
extern _ERROR_<_What...> __ok_v<__mexception<_What...> const>;
212+
210213
template <class _Ty>
211214
using __ok_t = decltype(__ok_v<_Ty>);
212215

213216
template <class... _Ts>
214-
using __mfind_error = decltype((__msuccess(), ..., __ok_t<_Ts>()));
217+
using __mfind_error = decltype((__ok_t<_Ts>(), ..., __msuccess()));
215218

216219
template <class _Arg>
217220
concept __ok = STDEXEC_IS_SAME(__ok_t<_Arg>, __msuccess);

0 commit comments

Comments
 (0)