Skip to content

Commit acea153

Browse files
authored
Merge 2025-06 LWG Motion 22
P3682R0 Remove std::execution::split
2 parents db62123 + 10c77ae commit acea153

File tree

1 file changed

+0
-373
lines changed

1 file changed

+0
-373
lines changed

source/exec.tex

Lines changed: 0 additions & 373 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,6 @@
633633
struct @\libglobal{bulk_t}@ { @\unspec@ };
634634
struct @\libglobal{bulk_chunked_t}@ { @\unspec@ };
635635
struct @\libglobal{bulk_unchunked_t}@ { @\unspec@ };
636-
struct @\libglobal{split_t}@ { @\unspec@ };
637636
struct @\libglobal{when_all_t}@ { @\unspec@ };
638637
struct @\libglobal{when_all_with_variant_t}@ { @\unspec@ };
639638
struct @\libglobal{into_variant_t}@ { @\unspec@ };
@@ -657,7 +656,6 @@
657656
inline constexpr bulk_t @\libglobal{bulk}@{};
658657
inline constexpr bulk_chunked_t @\libglobal{bulk_chunked}@{};
659658
inline constexpr bulk_unchunked_t @\libglobal{bulk_unchunked}@{};
660-
inline constexpr split_t @\libglobal{split}@{};
661659
inline constexpr when_all_t @\libglobal{when_all}@{};
662660
inline constexpr when_all_with_variant_t @\libglobal{when_all_with_variant}@{};
663661
inline constexpr into_variant_t @\libglobal{into_variant}@{};
@@ -4014,377 +4012,6 @@
40144012
ignore cancellation requests.
40154013
\end{note}
40164014

4017-
\rSec3[exec.split]{\tcode{execution::split}}
4018-
4019-
\pnum
4020-
\tcode{split} adapts an arbitrary sender
4021-
into a sender that can be connected multiple times.
4022-
4023-
\pnum
4024-
Let \exposid{split-env} be the type of an environment
4025-
such that, given an instance \tcode{env},
4026-
the expression \tcode{get_stop_token(env)} is well-formed and
4027-
has type \tcode{inplace_stop_token.}
4028-
4029-
\pnum
4030-
The name \tcode{split} denotes a pipeable sender adaptor object.
4031-
For a subexpression \tcode{sndr}, let \tcode{Sndr} be \tcode{decltype((sndr))}.
4032-
If \tcode{\libconcept{sender_in}<Sndr, \exposid{split-env}>} is \tcode{false},
4033-
\tcode{split(sndr)} is ill-formed.
4034-
4035-
\pnum
4036-
Otherwise, the expression \tcode{split(sndr)} is expression-equivalent to:
4037-
\begin{codeblock}
4038-
transform_sender(@\exposid{get-domain-early}@(sndr), @\exposid{make-sender}@(split, {}, sndr))
4039-
\end{codeblock}
4040-
except that \tcode{sndr} is evaluated only once.
4041-
\begin{note}
4042-
The default implementation of \tcode{transform_sender}
4043-
will have the effect of connecting the sender to a receiver.
4044-
It will return a sender with a different tag type.
4045-
\end{note}
4046-
4047-
\pnum
4048-
Let \exposid{local-state} denote the following exposition-only class template:
4049-
4050-
\begin{codeblock}
4051-
namespace std::execution {
4052-
struct @\exposid{local-state-base}@ { // \expos
4053-
virtual ~@\exposid{local-state-base}@() = default;
4054-
virtual void @\exposid{notify}@() noexcept = 0; // \expos
4055-
};
4056-
4057-
template<class Sndr, class Rcvr>
4058-
struct @\exposid{local-state}@ : @\exposid{local-state-base}@ { // \expos
4059-
using @\exposid{on-stop-callback}@ = // \expos
4060-
stop_callback_for_t<stop_token_of_t<env_of_t<Rcvr>>, @\exposid{on-stop-request}@>;
4061-
4062-
@\exposid{local-state}@(Sndr&& sndr, Rcvr& rcvr) noexcept;
4063-
~@\exposid{local-state}@();
4064-
4065-
void @\exposid{notify}@() noexcept override;
4066-
4067-
private:
4068-
optional<@\exposid{on-stop-callback}@> @\exposid{on_stop}@; // \expos
4069-
@\exposid{shared-state}@<Sndr>* @\exposid{sh_state}@; // \expos
4070-
Rcvr* @\exposid{rcvr}@; // \expos
4071-
};
4072-
}
4073-
\end{codeblock}
4074-
4075-
\begin{itemdecl}
4076-
@\exposid{local-state}@(Sndr&& sndr, Rcvr& rcvr) noexcept;
4077-
\end{itemdecl}
4078-
4079-
\begin{itemdescr}
4080-
\pnum
4081-
\effects
4082-
Equivalent to:
4083-
\begin{codeblock}
4084-
auto& [_, data, _] = sndr;
4085-
this->@\exposid{sh_state}@ = data.sh_state.get();
4086-
this->@\exposid{sh_state}@->@\exposid{inc-ref}@();
4087-
this->@\exposid{rcvr}@ = addressof(rcvr);
4088-
\end{codeblock}
4089-
\end{itemdescr}
4090-
4091-
\begin{itemdecl}
4092-
~@\exposid{local-state}@();
4093-
\end{itemdecl}
4094-
4095-
\begin{itemdescr}
4096-
\pnum
4097-
\effects
4098-
Equivalent to:
4099-
\begin{codeblock}
4100-
sh_state->@\exposid{dec-ref}@();
4101-
\end{codeblock}
4102-
\end{itemdescr}
4103-
4104-
\begin{itemdecl}
4105-
void @\exposid{notify}@() noexcept override;
4106-
\end{itemdecl}
4107-
4108-
\begin{itemdescr}
4109-
\pnum
4110-
\effects
4111-
Equivalent to:
4112-
\begin{codeblock}
4113-
@\exposid{on_stop}@.reset();
4114-
visit(
4115-
[this](const auto& tupl) noexcept -> void {
4116-
apply(
4117-
[this](auto tag, const auto&... args) noexcept -> void {
4118-
tag(std::move(*@\exposid{rcvr}@), args...);
4119-
},
4120-
tupl);
4121-
},
4122-
@\exposid{sh_state}@->result);
4123-
\end{codeblock}
4124-
\end{itemdescr}
4125-
4126-
\pnum
4127-
Let \exposid{split-receiver} denote
4128-
the following exposition-only class template:
4129-
\begin{codeblock}
4130-
namespace std::execution {
4131-
template<class Sndr>
4132-
struct @\exposid{split-receiver}@ { // \expos
4133-
using receiver_concept = receiver_t;
4134-
4135-
template<class Tag, class... Args>
4136-
void @\exposid{complete}@(Tag, Args&&... args) noexcept { // \expos
4137-
using tuple_t = @\exposid{decayed-tuple}@<Tag, Args...>;
4138-
try {
4139-
@\exposid{sh_state}@->result.template emplace<tuple_t>(Tag(), std::forward<Args>(args)...);
4140-
} catch (...) {
4141-
using tuple_t = tuple<set_error_t, exception_ptr>;
4142-
@\exposid{sh_state}@->result.template emplace<tuple_t>(set_error, current_exception());
4143-
}
4144-
@\exposid{sh_state}@->notify();
4145-
}
4146-
4147-
template<class... Args>
4148-
void set_value(Args&&... args) && noexcept {
4149-
@\exposid{complete}@(execution::set_value, std::forward<Args>(args)...);
4150-
}
4151-
4152-
template<class Error>
4153-
void set_error(Error&& err) && noexcept {
4154-
@\exposid{complete}@(execution::set_error, std::forward<Error>(err));
4155-
}
4156-
4157-
void set_stopped() && noexcept {
4158-
@\exposid{complete}@(execution::set_stopped);
4159-
}
4160-
4161-
struct @\exposid{env}@ { // \expos
4162-
@\exposid{shared-state}@<Sndr>* @\exposid{sh-state}@; // \expos
4163-
4164-
inplace_stop_token query(get_stop_token_t) const noexcept {
4165-
return @\exposid{sh-state}@->stop_src.get_token();
4166-
}
4167-
};
4168-
4169-
@\exposid{env}@ get_env() const noexcept {
4170-
return @\exposid{env}@{@\exposid{sh_state}@};
4171-
}
4172-
4173-
@\exposid{shared-state}@<Sndr>* @\exposid{sh_state}@; // \expos
4174-
};
4175-
}
4176-
\end{codeblock}
4177-
4178-
\pnum
4179-
Let \exposid{shared-state} denote the following exposition-only class template:
4180-
\begin{codeblock}
4181-
namespace std::execution {
4182-
template<class Sndr>
4183-
struct @\exposid{shared-state}@ {
4184-
using @\exposid{variant-type}@ = @\seebelow@; // \expos
4185-
using @\exposid{state-list-type}@ = @\seebelow@; // \expos
4186-
4187-
explicit @\exposid{shared-state}@(Sndr&& sndr);
4188-
4189-
void @\exposid{start-op}@() noexcept; // \expos
4190-
void @\exposid{notify}@() noexcept; // \expos
4191-
void @\exposid{inc-ref}@() noexcept; // \expos
4192-
void @\exposid{dec-ref}@() noexcept; // \expos
4193-
4194-
inplace_stop_source @\exposid{stop_src}@{}; // \expos
4195-
@\exposid{variant-type}@ @\exposid{result}@{}; // \expos
4196-
@\exposid{state-list-type}@ @\exposid{waiting_states}@; // \expos
4197-
atomic<bool> @\exposid{completed}@{false}; // \expos
4198-
atomic<size_t> @\exposid{ref_count}@{1}; // \expos
4199-
connect_result_t<Sndr, @\exposid{split-receiver}@<Sndr>> @\exposid{op_state}@; // \expos
4200-
};
4201-
}
4202-
\end{codeblock}
4203-
4204-
\pnum
4205-
Let \tcode{Sigs} be a pack of the arguments
4206-
to the \tcode{completion_signatures} specialization
4207-
named by \tcode{completion_signatures_of_t<Sndr>}.
4208-
For type \tcode{Tag} and pack \tcode{Args},
4209-
let \exposid{as-tuple} be an alias template
4210-
such that \tcode{\exposid{as-tuple}<Tag(Args...)>} denotes
4211-
the type \tcode{\exposid{decayed-tuple}<Tag, Args...>}.
4212-
Then \exposid{variant-type} denotes the type
4213-
\begin{codeblock}
4214-
variant<tuple<set_stopped_t>, tuple<set_error_t, exception_ptr>, @\exposid{as-tuple}@<Sigs>...>
4215-
\end{codeblock}
4216-
but with duplicate types removed.
4217-
4218-
\pnum
4219-
Let \exposid{state-list-type} be a type
4220-
that stores a list of pointers to \exposid{local-state-base} objects and
4221-
that permits atomic insertion.
4222-
4223-
\begin{itemdecl}
4224-
explicit @\exposid{shared-state}@(Sndr&& sndr);
4225-
\end{itemdecl}
4226-
4227-
\begin{itemdescr}
4228-
\pnum
4229-
\effects
4230-
Initializes \exposid{op_state} with the result of
4231-
\tcode{connect(std::forward<Sndr>(sndr), \exposid{split-re\-ceiver}\{this\})}.
4232-
4233-
\pnum
4234-
\ensures
4235-
\exposid{waiting_states} is empty, and \exposid{completed} is \tcode{false}.
4236-
\end{itemdescr}
4237-
4238-
\begin{itemdecl}
4239-
void @\exposid{start-op}@() noexcept;
4240-
\end{itemdecl}
4241-
4242-
\begin{itemdescr}
4243-
\pnum
4244-
\effects
4245-
Evaluates \tcode{\exposid{inc-ref}()}.
4246-
If \tcode{stop_src.stop_requested()} is \tcode{true},
4247-
evaluates \tcode{\exposid{notify}()};
4248-
otherwise, evaluates \tcode{start(\exposid{op_state})}.
4249-
\end{itemdescr}
4250-
4251-
\begin{itemdecl}
4252-
void @\exposid{notify}@() noexcept;
4253-
\end{itemdecl}
4254-
4255-
\begin{itemdescr}
4256-
\pnum
4257-
\effects
4258-
Atomically does the following:
4259-
\begin{itemize}
4260-
\item
4261-
Sets \tcode{completed} to \tcode{true}, and
4262-
\item
4263-
Exchanges \tcode{waiting_states} with an empty list,
4264-
storing the old value in a local \tcode{prior_states}.
4265-
\end{itemize}
4266-
Then, for each pointer \tcode{p} in \tcode{prior_states},
4267-
evaluates \tcode{p->\exposid{notify}()}.
4268-
Finally, evaluates \tcode{\exposid{dec-ref}()}.
4269-
\end{itemdescr}
4270-
4271-
\begin{itemdecl}
4272-
void @\exposid{inc-ref}@() noexcept;
4273-
\end{itemdecl}
4274-
4275-
\begin{itemdescr}
4276-
\pnum
4277-
\effects
4278-
Increments \exposid{ref_count}.
4279-
\end{itemdescr}
4280-
4281-
\begin{itemdecl}
4282-
void @\exposid{dec-ref}@() noexcept;
4283-
\end{itemdecl}
4284-
4285-
\begin{itemdescr}
4286-
\pnum
4287-
\effects
4288-
Decrements \exposid{ref_count}.
4289-
If the new value of \exposid{ref_count} is \tcode{0},
4290-
calls \tcode{delete this}.
4291-
4292-
\pnum
4293-
\sync
4294-
If an evaluation of \tcode{\exposid{dec-ref}()} does not
4295-
decrement the \tcode{ref_count} to \tcode{0} then
4296-
synchronizes with the evaluation of \tcode{dec-ref()}
4297-
that decrements \tcode{ref_count} to \tcode{0}.
4298-
\end{itemdescr}
4299-
4300-
\pnum
4301-
Let \exposid{split-impl-tag} be an empty exposition-only class type.
4302-
Given an expression \tcode{sndr},
4303-
the expression \tcode{split.transform_sender(sndr)} is equivalent to:
4304-
\begin{codeblock}
4305-
auto&& [tag, _, child] = sndr;
4306-
auto* sh_state = new @\exposid{shared-state}@{std::forward_like<decltype((sndr))>(child)};
4307-
return @\exposid{make-sender}@(@\exposid{split-impl-tag}@(), @\exposid{shared-wrapper}@{sh_state, tag});
4308-
\end{codeblock}
4309-
where \exposid{shared-wrapper} is an exposition-only class
4310-
that manages the reference count of the \exposid{shared-state} object
4311-
pointed to by sh_state.
4312-
\exposid{shared-wrapper} models \libconcept{copyable}
4313-
with move operations nulling out the moved-from object,
4314-
copy operations incrementing the reference count
4315-
by calling \tcode{sh_state->\exposid{inc-ref}()}, and
4316-
assignment operations performing a copy-and-swap operation.
4317-
The destructor has no effect if sh_state is null;
4318-
otherwise, it decrements the reference count
4319-
by evaluating \tcode{sh_state->\exposid{dec-ref}()}.
4320-
4321-
\pnum
4322-
The exposition-only class template \exposid{impls-for}\iref{exec.snd.general}
4323-
is specialized for \exposid{split-impl-tag} as follows:
4324-
\begin{codeblock}
4325-
namespace std::execution {
4326-
template<>
4327-
struct @\exposid{impls-for}@<@\exposid{split-impl-tag}@> : @\exposid{default-impls}@ {
4328-
static constexpr auto @\exposid{get-state}@ = @\seebelow@;
4329-
static constexpr auto @\exposid{start}@ = @\seebelow@;
4330-
};
4331-
}
4332-
\end{codeblock}
4333-
4334-
\pnum
4335-
The member
4336-
\tcode{\exposid{impls-for}<\exposid{split-impl-tag}>::\exposid{get-state}}
4337-
is initialized with a callable object equivalent to
4338-
the following lambda expression:
4339-
\begin{codeblock}
4340-
[]<class Sndr>(Sndr&& sndr, auto& rcvr) noexcept {
4341-
return @\exposid{local-state}@{std::forward<Sndr>(sndr), rcvr};
4342-
}
4343-
\end{codeblock}
4344-
4345-
\pnum
4346-
The member
4347-
\tcode{\exposid{impls-for}<\exposid{split-impl-tag}>::\exposid{start}}
4348-
is initialized with a callable object
4349-
that has a function call operator equivalent to the following:
4350-
\begin{codeblock}
4351-
template<class Sndr, class Rcvr>
4352-
void operator()(@\exposid{local-state}@<Sndr, Rcvr>& state, Rcvr& rcvr) const noexcept;
4353-
\end{codeblock}
4354-
4355-
\effects
4356-
If \tcode{state.\exposid{sh_state}->\exposid{completed}} is \tcode{true},
4357-
evaluates \tcode{state.\exposid{notify}()} and returns.
4358-
Otherwise, does the following in order:
4359-
\begin{itemize}
4360-
\item
4361-
Evaluates
4362-
\begin{codeblock}
4363-
state.@\exposid{on_stop}@.emplace(
4364-
get_stop_token(get_env(rcvr)),
4365-
@\exposid{on-stop-request}@{state.@\exposid{sh_state}@->@\exposid{stop_src}@});
4366-
\end{codeblock}
4367-
\item
4368-
Then atomically does the following:
4369-
\begin{itemize}
4370-
\item
4371-
Reads the value \tcode{c} of
4372-
\tcode{state.\exposid{sh_state}->\exposid{completed}}, and
4373-
\item
4374-
Inserts \tcode{addressof(state)} into
4375-
\tcode{state.\exposid{sh_state}->\exposid{waiting_states}}
4376-
if \tcode{c} is \tcode{false}.
4377-
\end{itemize}
4378-
\item
4379-
If \tcode{c} is \tcode{true},
4380-
calls \tcode{state.\exposid{notify}()} and returns.
4381-
\item
4382-
Otherwise,
4383-
if \tcode{addressof(state)} is the first item added to
4384-
\tcode{state.\exposid{sh_state}->\exposid{waiting_states}},
4385-
evaluates \tcode{state.\exposid{sh_state}->\exposid{start-op}()}.
4386-
\end{itemize}
4387-
43884015
\rSec3[exec.when.all]{\tcode{execution::when_all}}
43894016

43904017
\pnum

0 commit comments

Comments
 (0)