Skip to content

[Motions 2025 06 lwg 1] P3742R0 C++ Standard Library Issues #8014

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9bda6fb
LWG4198 schedule_from isn't starting the schedule sender if decay-cop…
burblebee Jun 25, 2025
ca8c1f5
LWG4202 enable-sender should be a variable template
burblebee Jun 25, 2025
b6d773d
LWG4203 Constraints on get-state functions are incorrect
burblebee Jun 25, 2025
9002782
LWG4204 specification of as-sndr2(Sig) in [exec.let] is incomplete
burblebee Jun 25, 2025
0450df0
LWG4205 let_[*].transform_env is specified in terms of the let_* send…
burblebee Jun 25, 2025
9e7d5b5
LWG4208 Wording needs to ensure that in connect(sndr, rcvr) that rcvr…
burblebee Jun 25, 2025
3b4b53e
LWG4209 default_domain::transform_env should be returning FWD-ENV(env)
burblebee Jun 25, 2025
4fb7ce6
LWG4188 ostream::sentry destructor should handle exceptions
burblebee Jun 25, 2025
978696a
LWG4200 The operation_state concept can be simplified
burblebee Jun 25, 2025
0d0bce1
LWG4201 with-await-transform::await_transform should not use a deduce…
burblebee Jun 25, 2025
d4ae4b0
LWG4217 Clarify mdspan layout mapping requirements for rank == 0
burblebee Jun 25, 2025
4087822
LWG4222 expected constructor from a single value missing a constraint
burblebee Jun 25, 2025
6cb65d4
LWG4224 Philox engines should be freestanding
burblebee Jun 25, 2025
527b455
LWG4227 Missing noexcept operator in [exec.when.all]
burblebee Jun 25, 2025
fbc37ec
LWG4231 datapar::chunk<N> should use simd-size-type instead of size_t
burblebee Jun 25, 2025
0b83496
LWG4232 datapar::resize does not resize
burblebee Jun 25, 2025
c1285b7
LWG4233 The helper lambda of std::erase for hive should specify retur…
burblebee Jun 25, 2025
be45d8a
LWG4234 Including <hive> doesn't provide std::begin/end
burblebee Jun 25, 2025
de326ef
LWG4235 cache_latest_view and to_input_view miss reserve_hint
burblebee Jun 25, 2025
543742d
LWG4236 chunk_view::outer-iterator::value_type should provide reserve…
burblebee Jun 25, 2025
6ff27d1
LWG4239 flat_map's transparent comparator no longer works for string …
burblebee Jun 25, 2025
660bdec
LWG4242 ranges::distance does not work with volatile iterators
burblebee Jun 25, 2025
b06b819
LWG4245 Operators that interact with counted_iterator and default_sen…
burblebee Jun 25, 2025
9d78e1e
LWG4247 Header <stdbit.h> is not yet freestanding
burblebee Jun 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions source/containers.tex
Original file line number Diff line number Diff line change
Expand Up @@ -8942,7 +8942,7 @@

\indexlibrarymember{erase}{hive}%
\begin{itemdecl}
template<class T, class Allocator, class U>
template<class T, class Allocator, class U = T>
typename hive<T, Allocator>::size_type
erase(hive<T, Allocator>& c, const U& value);
\end{itemdecl}
Expand All @@ -8952,7 +8952,7 @@
\effects
Equivalent to:
\begin{codeblock}
return erase_if(c, [&](auto& elem) { return elem == value; });
return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
\end{codeblock}
\end{itemdescr}

Expand Down Expand Up @@ -17940,7 +17940,7 @@
\tcode{*this} and \tcode{args...} are unchanged.
Otherwise equivalent to:
\begin{codeblock}
auto key_it = ranges::upper_bound(@\exposid{c}@.keys, k, @\exposid{compare}@);
auto key_it = upper_bound(@\exposid{c}@.keys.begin(), @\exposid{c}@.keys.end(), k, @\exposid{compare}@);
auto value_it = @\exposid{c}@.values.begin() + distance(@\exposid{c}@.keys.begin(), key_it);
@\exposid{c}@.keys.emplace(key_it, std::forward<K>(k));
@\exposid{c}@.values.emplace(value_it, std::forward<Args>(args)...);
Expand Down Expand Up @@ -21803,6 +21803,13 @@
\pnum
\returns
$s_r$ as defined in \tcode{m.is_strided()} above.

\pnum
\begin{note}
It is not required for \tcode{m.stride(r)} to be well-formed
if \tcode{m.extents().rank()} is zero,
even if \tcode{m.is_always_strided()} is \tcode{true}.
\end{note}
\end{itemdescr}

\begin{itemdecl}
Expand Down
98 changes: 66 additions & 32 deletions source/exec.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1189,9 +1189,8 @@
template<class O>
concept @\deflibconcept{operation_state}@ =
@\libconcept{derived_from}@<typename O::operation_state_concept, operation_state_t> &&
is_object_v<O> &&
requires (O& o) {
{ start(o) } noexcept;
start(o);
};
}
\end{codeblock}
Expand Down Expand Up @@ -1279,6 +1278,8 @@
the expression \tcode{\exposid{FWD-ENV}(env).query(q, as...)} is ill-formed
if \tcode{forwarding_query(q)} is \tcode{false};
otherwise, it is expression-equivalent to \tcode{env.query(q, as...)}.
The type \tcode{\exposid{FWD-ENV-T}(Env)} is
\tcode{decltype(\exposid{FWD-ENV}(declval<Env>()))}.

\pnum
For a query object \tcode{q} and \tcode{a} subexpression \tcode{v},
Expand Down Expand Up @@ -1946,9 +1947,12 @@
@\exposconcept{is-sender}@<Sndr> ||
@\exposconcept{is-awaitable}@<Sndr, @\exposid{env-promise}@<env<>>>; // \ref{exec.awaitable}

template<class Sndr>
inline constexpr bool enable_sender = @\exposconcept{enable-sender}@<Sndr>;

template<class Sndr>
concept @\deflibconcept{sender}@ =
bool(@\exposconcept{enable-sender}@<remove_cvref_t<Sndr>>) &&
enable_sender<remove_cvref_t<Sndr>> &&
requires (const remove_cvref_t<Sndr>& sndr) {
{ get_env(sndr) } -> @\exposconcept{queryable}@;
} &&
Expand Down Expand Up @@ -1989,6 +1993,17 @@
starting the resulting operation state
are permissible completions for \tcode{Sndr} and \tcode{Env}.

\pnum
\remarks
Pursuant to \ref{namespace.std},
users may specialize \tcode{enable_sender} to
\tcode{true} for cv-unqualified program-defined types that
model \libconcept{sender}, and
\tcode{false} for types that do not.
Such specializations shall
be usable in constant expressions\iref{expr.const} and
have type \tcode{const bool}.

\pnum
A type models
the exposition-only concept \defexposconcept{valid-completion-signatures}
Expand Down Expand Up @@ -2141,8 +2156,9 @@
}

template<@\exposconcept{has-as-awaitable}@<Derived> T>
decltype(auto) await_transform(T&& value)
noexcept(noexcept(std::forward<T>(value).as_awaitable(declval<Derived&>()))) {
auto await_transform(T&& value)
noexcept(noexcept(std::forward<T>(value).as_awaitable(declval<Derived&>())))
-> decltype(std::forward<T>(value).as_awaitable(declval<Derived&>())) {
return std::forward<T>(value).as_awaitable(static_cast<Derived&>(*this));
}
};
Expand Down Expand Up @@ -2231,7 +2247,7 @@
tag_of_t<Sndr>().transform_env(std::forward<Sndr>(sndr), std::forward<Env>(env))
\end{codeblock}
if that expression is well-formed;
otherwise, \tcode{static_cast<Env>(std::forward<Env>(env))}.
otherwise, \tcode{\exposid{FWD-ENV}(std::forward<Env>(env))}.

\pnum
\mandates
Expand Down Expand Up @@ -2561,6 +2577,9 @@
\item
Otherwise, \tcode{\exposid{connect-awaitable}(new_sndr, rcvr)}.
\end{itemize}
%%FIXME: This sentence should be joined with the previous sentences;
%%FIXME: how to do that with the embeded "madates"??
Except that \tcode{rcvr} is evaluated only once.

\mandates
\tcode{\libconcept{sender}<Sndr> \&\& \libconcept{receiver}<Rcvr>} is \tcode{true}.
Expand Down Expand Up @@ -2995,7 +3014,7 @@
is initialized with a callable object equivalent to the following lambda:
\begin{codeblock}
[]<class Sndr, class Rcvr>(Sndr&& sndr, Rcvr& rcvr) noexcept(@\seebelow@)
requires @\libconcept{sender_in}@<@\exposid{child-type}@<Sndr>, env_of_t<Rcvr>> {
requires @\libconcept{sender_in}@<@\exposid{child-type}@<Sndr>, @\exposid{FWD-ENV-T}@(env_of_t<Rcvr>)> {

auto& [_, sch, child] = sndr;

Expand Down Expand Up @@ -3025,12 +3044,20 @@
\pnum
Let \tcode{Sigs} be
a pack of the arguments to the \tcode{completion_signatures} specialization
named by \tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, env_of_t<Rcvr>>}.
Let \exposid{as-tuple} be an alias template
that transforms a completion signature \tcode{Tag(Args...)} into
the tuple specialization \tcode{\exposid{decayed-tuple}<Tag, Args...>}.
named by \tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, \exposid{FWD-ENV-T}(env_of_t<Rcvr>)>}.
Let \exposid{as-tuple} be an alias template such that
\tcode{\exposid{as-tuple}<Tag(Args...)>} denotes
the type \tcode{\exposid{decayed-tuple}<Tag, Args...>}, and
let \exposid{is-no\-throw-decay-copy-sig} be a variable template such that
\tcode{auto(\exposid{is-nothrow-decay-copy-sig}<Tag(Args...\linebreak{})>)} is
a constant expression of type \tcode{bool} and
equal to \tcode{(is_nothrow_constructible_v<decay_t<Args>, Args> \&\& ...)}.
Let \exposid{error-completion} be a pack consisting of
the type \tcode{set_error_t(exception_ptr)}
if \tcode{(\exposid{is-nothrow-decay-copy-sig}<Sigs> \&\&...)} is \tcode{false},
and an empty pack otherwise.
Then \tcode{variant_t} denotes
the type \tcode{variant<monostate, \exposid{as-tuple}<Sigs>...>},
the type \tcode{variant<monostate, \exposid{as-tuple}<Sigs>..., \exposid{error-completion}...>},
except with duplicate types removed.

\pnum
Expand Down Expand Up @@ -3081,15 +3108,14 @@
[]<class Tag, class... Args>(auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept
-> void {
using result_t = @\exposid{decayed-tuple}@<Tag, Args...>;
constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>;
constexpr bool nothrow = (is_nothrow_constructible_v<decay_t<Args>, Args> && ...);

try {
state.@\exposid{async-result}@.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
} catch (...) {
if constexpr (!nothrow) {
set_error(std::move(rcvr), current_exception());
return;
}
if constexpr (!nothrow)
state.@\exposid{async-result}@.template emplace<tuple<set_error_t,
exception_ptr>>(set_error, current_exception());
}
start(state.@\exposid{op-state}@);
};
Expand Down Expand Up @@ -3493,9 +3519,13 @@
\item
given a query object \tcode{q},
the expression \tcode{e.query(q)} is expression-equivalent
to \tcode{\exposid{env}.query(q)} if that expression is valid,
otherwise \tcode{e.query(q)} is expression-equivalent
to \tcode{get_env(\exposid{rcvr}).query(q)}.
to \tcode{\exposid{env}.query(q)} if that expression is valid;
otherwise,
if the type of \tcode{q} satisfies \exposconcept{forwarding-query},
\tcode{e.query(q)} is expression-equivalent
to \tcode{get_env(\exposid{rcvr}).query(q)};
otherwise,
\tcode{e.query(q)} is ill-formed.
\end{itemize}

\pnum
Expand All @@ -3522,7 +3552,7 @@
\pnum
Let \tcode{Sigs} be a pack of the arguments
to the \tcode{completion_signatures} specialization named by
\tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, env_of_t<Rcvr>>}.
\tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, \exposid{FWD-ENV-T}(env_of_t<Rcvr>)>}.
Let \tcode{LetSigs} be a pack of those types in \tcode{Sigs}
with a return type of \tcode{\exposid{decayed-typeof}<\exposid{set-cpo}>}.
Let \exposid{as-tuple} be an alias template
Expand All @@ -3540,7 +3570,7 @@
Then \tcode{ops2_variant_t} denotes
the type
\begin{codeblock}
variant<monostate, connect_result_t<@\exposid{as-sndr2}@<LetSigs>, @\exposid{receiver2}@<Rcvr, Env>>...>
variant<monostate, connect_result_t<@\exposid{as-sndr2}@<LetSigs>, @\exposid{receiver2}@<Rcvr, env_t>>...>
\end{codeblock}
except with duplicate types removed.

Expand Down Expand Up @@ -3585,8 +3615,11 @@
is \tcode{false},
then the expression \tcode{\exposid{let-cpo}.transform_env(sndr, env)}
is ill-formed.
Otherwise, it is equal to
\tcode{\exposid{JOIN-ENV}(\exposid{let-env}(sndr), \exposid{FWD-ENV}(env))}.
Otherwise, it is equal to:
\begin{codeblock}
auto& [_, _, child] = sndr;
return @\exposid{JOIN-ENV}@(@\exposid{let-env}@(child), @\exposid{FWD-ENV}@(env));
\end{codeblock}

\pnum
Let the subexpression \tcode{out_sndr} denote
Expand Down Expand Up @@ -4153,7 +4186,8 @@
\tcode{e.query(get_stop_token)} is expression-equivalent to
\tcode{state.\exposid{stop-src}.get_token()}, and
\item
given a query object \tcode{q} with type other than \cv{} \tcode{stop_token_t},
given a query object \tcode{q} with type other than \cv{} \tcode{stop_token_t}
and whose type satisfies \exposconceptx{forwarding-que\-ry}{forwarding-query},
\tcode{e.query(q)} is expression-equivalent to \tcode{get_env(rcvr).query(q)}.
\end{itemize}

Expand All @@ -4162,7 +4196,7 @@
is initialized with a callable object
equivalent to the following lambda expression:
\begin{codeblock}
[]<class Sndr, class Rcvr>(Sndr&& sndr, Rcvr& rcvr) noexcept(@$e$@) -> decltype(@$e$@) {
[]<class Sndr, class Rcvr>(Sndr&& sndr, Rcvr& rcvr) noexcept(noexcept(@$e$@)) -> decltype(@$e$@) {
return @$e$@;
}
\end{codeblock}
Expand All @@ -4180,7 +4214,7 @@

template<class Rcvr>
struct @\exposid{make-state}@ {
template<@\exposconcept{max-1-sender-in}@<env_of_t<Rcvr>>... Sndrs>
template<@\exposconcept{max-1-sender-in}@<@\exposid{FWD-ENV-T}@(env_of_t<Rcvr>)>... Sndrs>
auto operator()(auto, auto, Sndrs&&... sndrs) const {
using values_tuple = @\seebelow@;
using errors_variant = @\seebelow@;
Expand Down Expand Up @@ -4217,7 +4251,7 @@
\pnum
The alias \tcode{values_tuple} denotes the type
\begin{codeblock}
tuple<value_types_of_t<Sndrs, env_of_t<Rcvr>, @\exposid{decayed-tuple}@, optional>...>
tuple<value_types_of_t<Sndrs, @\exposid{FWD-ENV-T}@(env_of_t<Rcvr>), @\exposid{decayed-tuple}@, optional>...>
\end{codeblock}
if that type is well-formed; otherwise, \tcode{tuple<>}.

Expand Down Expand Up @@ -4405,7 +4439,7 @@
is initialized with a callable object equivalent to the following lambda:
\begin{codeblock}
[]<class Sndr, class Rcvr>(Sndr&& sndr, Rcvr& rcvr) noexcept
-> type_identity<value_types_of_t<@\exposid{child-type}@<Sndr>, env_of_t<Rcvr>>> {
-> type_identity<value_types_of_t<@\exposid{child-type}@<Sndr>, @\exposid{FWD-ENV-T}@(env_of_t<Rcvr>)>> {
return {};
}
\end{codeblock}
Expand Down Expand Up @@ -4450,14 +4484,14 @@
\tcode{Env} is \tcode{decltype((env))}.
If \tcode{\exposconcept{sender-for}<Sndr, stopped_as_optional_t>}
is \tcode{false}, or
if the type \tcode{\exposid{single-sender-value-type}<Sndr, Env>}
if the type \tcode{\exposid{single-sender-value-type}<\linebreak{}\exposid{child-type}<Sndr>, \exposid{FWD-ENV-T}(Env)>}
is ill-formed or \tcode{void},
then the expression \tcode{stopped_as_optional.transform_sender(sndr, env)}
then the expression \tcode{stopped_as_optional.\linebreak{}transform_sender(sndr, env)}
is ill-formed;
otherwise, it is equivalent to:
\begin{codeblock}
auto&& [_, _, child] = sndr;
using V = @\exposid{single-sender-value-type}@<Sndr, Env>;
using V = @\exposid{single-sender-value-type}@<@\exposid{child-type}@<Sndr>, @\exposid{FWD-ENV-T}@(Env)>;
return let_stopped(
then(std::forward_like<Sndr>(child),
[]<class... Ts>(Ts&&... ts) noexcept(is_nothrow_constructible_v<V, Ts...>) {
Expand Down
3 changes: 2 additions & 1 deletion source/iostreams.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6257,7 +6257,8 @@
is
\tcode{true},
calls
\tcode{os.rdbuf()->pubsync()}. If that function returns $-1$, sets \tcode{badbit} in
\tcode{os.rdbuf()->pubsync()}. If that function returns $-1$ or
exits via an exception, sets \tcode{badbit} in
\tcode{os.rdstate()} without propagating an exception.
\end{itemdescr}

Expand Down
21 changes: 14 additions & 7 deletions source/iterators.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3068,7 +3068,13 @@
\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return last - static_cast<const decay_t<I>\&>(first);}
Equivalent to:
\begin{codeblock}
if constexpr (!is_array_v<remove_reference_t<I>>)
return last - first;
else
return last - static_cast<decay_t<I>>(first);
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{distance}%
Expand Down Expand Up @@ -5965,9 +5971,9 @@
friend constexpr iter_difference_t<I2> operator-(
const counted_iterator& x, const counted_iterator<I2>& y);
friend constexpr iter_difference_t<I> operator-(
const counted_iterator& x, default_sentinel_t);
const counted_iterator& x, default_sentinel_t) noexcept;
friend constexpr iter_difference_t<I> operator-(
default_sentinel_t, const counted_iterator& y);
default_sentinel_t, const counted_iterator& y) noexcept;
constexpr counted_iterator& operator-=(iter_difference_t<I> n)
requires @\libconcept{random_access_iterator}@<I>;

Expand All @@ -5978,7 +5984,7 @@
friend constexpr bool operator==(
const counted_iterator& x, const counted_iterator<I2>& y);
friend constexpr bool operator==(
const counted_iterator& x, default_sentinel_t);
const counted_iterator& x, default_sentinel_t) noexcept;

template<@\libconcept{common_with}@<I> I2>
friend constexpr strong_ordering operator<=>(
Expand Down Expand Up @@ -6309,7 +6315,7 @@
\indexlibrarymember{operator-}{counted_iterator}%
\begin{itemdecl}
friend constexpr iter_difference_t<I> operator-(
const counted_iterator& x, default_sentinel_t);
const counted_iterator& x, default_sentinel_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
Expand All @@ -6322,7 +6328,7 @@
\indexlibrarymember{operator-}{counted_iterator}%
\begin{itemdecl}
friend constexpr iter_difference_t<I> operator-(
default_sentinel_t, const counted_iterator& y);
default_sentinel_t, const counted_iterator& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
Expand Down Expand Up @@ -6375,7 +6381,7 @@
\indexlibrarymember{operator==}{counted_iterator}%
\begin{itemdecl}
friend constexpr bool operator==(
const counted_iterator& x, default_sentinel_t);
const counted_iterator& x, default_sentinel_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
Expand Down Expand Up @@ -7243,6 +7249,7 @@
\libheaderrefx{flat_map}{flat.map.syn},
\libheaderrefx{flat_set}{flat.set.syn},
\libheaderrefx{forward_list}{forward.list.syn},
\libheaderref{hive},
\libheaderrefx{inplace_vector}{inplace.vector.syn},
\libheaderref{list},
\libheaderrefx{map}{associative.map.syn},
Expand Down
1 change: 1 addition & 0 deletions source/lib-intro.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1623,6 +1623,7 @@
\ref{expected} & Expected objects & \tcode{<expected>} \\ \rowsep
\ref{function.objects} & Function objects & \tcode{<functional>} \\ \rowsep
\ref{bit} & Bit manipulation & \tcode{<bit>} \\ \rowsep
\ref{stdbit.h.syn} & C-compatible bit manipulation & \tcode{<stdbit.h>} \\ \rowsep
\ref{array} & Class template \tcode{array} & \tcode{<array>} \\ \rowsep
\ref{inplace.vector} & Class template \tcode{inplace_vector} & \tcode{<inplace_vector>} \\ \rowsep
\ref{views.contiguous} & Contiguous access & \tcode{<span>} \\ \rowsep
Expand Down
Loading