diff --git a/stl/inc/execution b/stl/inc/execution index 9df2458b2e2..c22f21a7d2c 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -5021,6 +5021,647 @@ _FwdIt2 adjacent_difference(_ExPo&&, const _FwdIt1 _First, const _FwdIt1 _Last, _Get_unwrapped_n(_Dest, _Idl_distance<_FwdIt1>(_UFirst, _ULast)), _Pass_fn(_Diff_op))); return _Dest; } + +#ifdef __cpp_lib_executors +namespace execution { + template + concept _Movable_value = move_constructible> && constructible_from, _Ty>; + + template + concept _Scheduler_base = copy_constructible> // + && equality_comparable> // + && is_nothrow_copy_constructible_v> // + && is_nothrow_destructible_v> // + && noexcept(_STD declval>() == _STD declval>()); + + namespace _Schedule { + struct _Cpo { + template <_Scheduler_base _Scheduler> + requires tag_invocable<_Cpo, _Scheduler> + constexpr auto operator()(_Scheduler _Sched) const noexcept(nothrow_tag_invocable<_Cpo, _Scheduler>) { + return tag_invoke(*this, _STD forward<_Scheduler>(_Sched)); + } + }; + } // namespace _Schedule + using schedule_t = _Schedule::_Cpo; + + inline namespace _Cpos { + inline constexpr _Schedule::_Cpo schedule; + } // namespace _Cpos + + template + concept scheduler = _Scheduler_base<_Sender> && requires(_Sender&& __s) { + {_EXEC schedule(_STD forward<_Sender>(__s))}; + }; + + enum class forward_progress_guarantee { concurrent, parallel, weakly_parallel }; + + namespace _Get_forward_progress_guarantee { + struct _Cpo { + template + _NODISCARD constexpr auto operator()(_Scheduler&& _Sched) const noexcept { + if constexpr (tag_observable<_Cpo, _Scheduler>) { + return tag_invoke(*this, _STD as_const(_Sched)); + } else { + return forward_progress_guarantee::weakly_parallel; + } + } + }; + } // namespace _Get_forward_progress_guarantee + using get_forward_progress_guarantee_t = _Get_forward_progress_guarantee::_Cpo; + + inline namespace _Cpos { + inline constexpr _Get_forward_progress_guarantee::_Cpo get_forward_progress_guarantee; + } // namespace _Cpos +} // namespace execution + +namespace this_thread { + namespace _Execute_may_block_caller { + struct _Cpo { + template <_EXEC scheduler _Scheduler> + _NODISCARD constexpr bool operator()(_Scheduler&& _Sched) const noexcept { + if constexpr (tag_observable<_Cpo, _Scheduler> // + && same_as, bool>) { + return tag_invoke(*this, _STD as_const(_Sched)); + } else { + return true; + } + } + }; + } // namespace _Execute_may_block_caller + using execute_may_block_caller_t = _Execute_may_block_caller::_Cpo; + + inline namespace _Cpos { + inline constexpr _Execute_may_block_caller::_Cpo execute_may_block_caller; + } // namespace _Cpos +} // namespace this_thread + +namespace execution { + namespace _Set_value { + struct _Cpo { + // clang-format off + template <_Movable_value _Receiver, class... _Types> + requires tag_invocable<_Cpo, _Receiver, _Types...> + _NODISCARD constexpr auto operator()(_Receiver&& _Rec, _Types&&... _Args) const noexcept( + nothrow_tag_invocable<_Cpo, _Receiver, _Types...>) { + // clang-format on + return tag_invoke(*this, _STD forward<_Receiver>(_Rec), _STD forward<_Types>(_Args)...); + } + }; + } // namespace _Set_value + using set_value_t = _Set_value::_Cpo; + + inline namespace _Cpos { + inline constexpr _Set_value::_Cpo set_value; + } + + namespace _Set_error { + struct _Cpo { + // clang-format off + template <_Movable_value _Receiver, class _Exception> + requires tag_invocable<_Cpo, _Receiver, _Exception> + _NODISCARD constexpr auto operator()(_Receiver&& _Rec, _Exception&& _Except) const + noexcept(nothrow_tag_invocable<_Cpo, _Receiver, _Exception>) { + // clang-format on + return tag_invoke(*this, _STD forward<_Receiver>(_Rec), _STD forward<_Exception>(_Except)); + } + }; + } // namespace _Set_error + using set_error_t = _Set_error::_Cpo; + + inline namespace _Cpos { + inline constexpr _Set_error::_Cpo set_error; + } + + namespace _Set_done { + struct _Cpo { + // clang-format off + template <_Movable_value _Receiver> + requires tag_invocable<_Cpo, _Receiver> + _NODISCARD constexpr auto operator()(_Receiver&& _Rec) const + noexcept(nothrow_tag_invocable<_Cpo, _Receiver>) { + // clang-format on + return tag_invoke(*this, _STD forward<_Receiver>(_Rec)); + } + }; + } // namespace _Set_done + using set_done_t = _Set_done::_Cpo; + + inline namespace _Cpos { + inline constexpr _Set_done::_Cpo set_done; + } + + // clang-format off + template + concept receiver = _Movable_value<_Ty> && requires (remove_cvref_t<_Ty>&& __t, _Exception&& __e) { + { _EXEC set_done(_STD move(__t)) } noexcept; + { _EXEC set_error(_STD move(__t), _STD forward<_Exception>(__e)) } noexcept; + }; + + template + concept receiver_of = receiver<_Ty> && requires (remove_cvref_t<_Ty>&& __t, _Types&&... __args) { + { _EXEC set_value(_STD move(__t), _STD forward<_Types>(__args)...) }; + }; + // clang-format on + + namespace _Get_scheduler { + struct _Cpo { + // clang-format off + template + requires tag_observable<_Cpo, _Receiver> + _NODISCARD constexpr auto operator()(_Receiver&& _Rec) const noexcept { + // clang-format on + return tag_invoke(*this, _STD as_const(_Rec)); + } + }; + } // namespace _Get_scheduler + using get_scheduler_t = _Get_scheduler::_Cpo; + + inline namespace _Cpos { + inline constexpr _Get_scheduler::_Cpo get_scheduler; + } + + namespace _Get_allocator { + struct _Cpo { + // clang-format off + template + requires tag_observable<_Cpo, _Receiver> + _NODISCARD constexpr auto operator()(_Receiver&& _Rec) const noexcept { + // clang-format on + return tag_invoke(*this, _STD as_const(_Rec)); + } + }; + } // namespace _Get_allocator + using get_allocator_t = _Get_allocator::_Cpo; + + inline namespace _Cpos { + inline constexpr _Get_allocator::_Cpo get_allocator; + } + + namespace _Get_stop_token { + struct _Cpo { + template + _NODISCARD constexpr auto operator()(_Receiver&& _Rec) const noexcept { + if constexpr (tag_observable<_Cpo, _Receiver>) { + return tag_invoke(*this, _STD as_const(_Rec)); + } else { + return never_stop_token{}; + } + } + }; + } // namespace _Get_stop_token + using get_stop_token_t = _Get_stop_token::_Cpo; + + inline namespace _Cpos { + inline constexpr _Get_stop_token::_Cpo get_stop_token; + } + + namespace _Operation_state_start { + struct _Cpo { + // clang-format off + template + requires destructible<_Ty> && is_object_v<_Ty> && nothrow_tag_invocable<_Cpo, _Ty&> + _NODISCARD constexpr auto operator()(_Ty& _State) const noexcept { + // clang-format on + return tag_invoke(*this, _State); + } + }; + } // namespace _Operation_state_start + using start_t = _Operation_state_start::_Cpo; + + inline namespace _Cpos { + inline constexpr _Operation_state_start::_Cpo start; + } + + template + concept operation_state = destructible<_Ty> && is_object_v<_Ty> && requires(_Ty& __t) { + // clang-format off + {_EXEC start(__t)} noexcept; + // clang-format on + }; + + template