Skip to content

Commit 2871048

Browse files
committed
Merge 2025-06 LWG Motion 1
P3742R0 C++ Standard Library Issues to be moved in Sofia, June 2025
2 parents 06614c2 + 54ce6ab commit 2871048

File tree

8 files changed

+155
-55
lines changed

8 files changed

+155
-55
lines changed

source/containers.tex

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8942,7 +8942,7 @@
89428942

89438943
\indexlibrarymember{erase}{hive}%
89448944
\begin{itemdecl}
8945-
template<class T, class Allocator, class U>
8945+
template<class T, class Allocator, class U = T>
89468946
typename hive<T, Allocator>::size_type
89478947
erase(hive<T, Allocator>& c, const U& value);
89488948
\end{itemdecl}
@@ -8952,7 +8952,7 @@
89528952
\effects
89538953
Equivalent to:
89548954
\begin{codeblock}
8955-
return erase_if(c, [&](auto& elem) { return elem == value; });
8955+
return erase_if(c, [&](const auto& elem) -> bool { return elem == value; });
89568956
\end{codeblock}
89578957
\end{itemdescr}
89588958

@@ -17940,7 +17940,7 @@
1794017940
\tcode{*this} and \tcode{args...} are unchanged.
1794117941
Otherwise equivalent to:
1794217942
\begin{codeblock}
17943-
auto key_it = ranges::upper_bound(@\exposid{c}@.keys, k, @\exposid{compare}@);
17943+
auto key_it = upper_bound(@\exposid{c}@.keys.begin(), @\exposid{c}@.keys.end(), k, @\exposid{compare}@);
1794417944
auto value_it = @\exposid{c}@.values.begin() + distance(@\exposid{c}@.keys.begin(), key_it);
1794517945
@\exposid{c}@.keys.emplace(key_it, std::forward<K>(k));
1794617946
@\exposid{c}@.values.emplace(value_it, std::forward<Args>(args)...);
@@ -21803,6 +21803,13 @@
2180321803
\pnum
2180421804
\returns
2180521805
$s_r$ as defined in \tcode{m.is_strided()} above.
21806+
21807+
\pnum
21808+
\begin{note}
21809+
It is not required for \tcode{m.stride(r)} to be well-formed
21810+
if \tcode{m.extents().rank()} is zero,
21811+
even if \tcode{m.is_always_strided()} is \tcode{true}.
21812+
\end{note}
2180621813
\end{itemdescr}
2180721814

2180821815
\begin{itemdecl}

source/exec.tex

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,9 +1189,8 @@
11891189
template<class O>
11901190
concept @\deflibconcept{operation_state}@ =
11911191
@\libconcept{derived_from}@<typename O::operation_state_concept, operation_state_t> &&
1192-
is_object_v<O> &&
11931192
requires (O& o) {
1194-
{ start(o) } noexcept;
1193+
start(o);
11951194
};
11961195
}
11971196
\end{codeblock}
@@ -1279,6 +1278,8 @@
12791278
the expression \tcode{\exposid{FWD-ENV}(env).query(q, as...)} is ill-formed
12801279
if \tcode{forwarding_query(q)} is \tcode{false};
12811280
otherwise, it is expression-equivalent to \tcode{env.query(q, as...)}.
1281+
The type \tcode{\exposid{FWD-ENV-T}(Env)} is
1282+
\tcode{decltype(\exposid{FWD-ENV}(declval<Env>()))}.
12821283

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

1950+
template<class Sndr>
1951+
inline constexpr bool enable_sender = @\exposconcept{enable-sender}@<Sndr>;
1952+
19491953
template<class Sndr>
19501954
concept @\deflibconcept{sender}@ =
1951-
bool(@\exposconcept{enable-sender}@<remove_cvref_t<Sndr>>) &&
1955+
enable_sender<remove_cvref_t<Sndr>> &&
19521956
requires (const remove_cvref_t<Sndr>& sndr) {
19531957
{ get_env(sndr) } -> @\exposconcept{queryable}@;
19541958
} &&
@@ -1989,6 +1993,17 @@
19891993
starting the resulting operation state
19901994
are permissible completions for \tcode{Sndr} and \tcode{Env}.
19911995

1996+
\pnum
1997+
\remarks
1998+
Pursuant to \ref{namespace.std},
1999+
users may specialize \tcode{enable_sender} to
2000+
\tcode{true} for cv-unqualified program-defined types that
2001+
model \libconcept{sender}, and
2002+
\tcode{false} for types that do not.
2003+
Such specializations shall
2004+
be usable in constant expressions\iref{expr.const} and
2005+
have type \tcode{const bool}.
2006+
19922007
\pnum
19932008
A type models
19942009
the exposition-only concept \defexposconcept{valid-completion-signatures}
@@ -2141,8 +2156,9 @@
21412156
}
21422157

21432158
template<@\exposconcept{has-as-awaitable}@<Derived> T>
2144-
decltype(auto) await_transform(T&& value)
2145-
noexcept(noexcept(std::forward<T>(value).as_awaitable(declval<Derived&>()))) {
2159+
auto await_transform(T&& value)
2160+
noexcept(noexcept(std::forward<T>(value).as_awaitable(declval<Derived&>())))
2161+
-> decltype(std::forward<T>(value).as_awaitable(declval<Derived&>())) {
21462162
return std::forward<T>(value).as_awaitable(static_cast<Derived&>(*this));
21472163
}
21482164
};
@@ -2231,7 +2247,7 @@
22312247
tag_of_t<Sndr>().transform_env(std::forward<Sndr>(sndr), std::forward<Env>(env))
22322248
\end{codeblock}
22332249
if that expression is well-formed;
2234-
otherwise, \tcode{static_cast<Env>(std::forward<Env>(env))}.
2250+
otherwise, \tcode{\exposid{FWD-ENV}(std::forward<Env>(env))}.
22352251

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

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

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

@@ -3025,12 +3044,20 @@
30253044
\pnum
30263045
Let \tcode{Sigs} be
30273046
a pack of the arguments to the \tcode{completion_signatures} specialization
3028-
named by \tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, env_of_t<Rcvr>>}.
3029-
Let \exposid{as-tuple} be an alias template
3030-
that transforms a completion signature \tcode{Tag(Args...)} into
3031-
the tuple specialization \tcode{\exposid{decayed-tuple}<Tag, Args...>}.
3047+
named by \tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, \exposid{FWD-ENV-T}(env_of_t<Rcvr>)>}.
3048+
Let \exposid{as-tuple} be an alias template such that
3049+
\tcode{\exposid{as-tuple}<Tag(Args...)>} denotes
3050+
the type \tcode{\exposid{decayed-tuple}<Tag, Args...>}, and
3051+
let \exposid{is-no\-throw-decay-copy-sig} be a variable template such that
3052+
\tcode{auto(\exposid{is-nothrow-decay-copy-sig}<Tag(Args...\linebreak{})>)} is
3053+
a constant expression of type \tcode{bool} and
3054+
equal to \tcode{(is_nothrow_constructible_v<decay_t<Args>, Args> \&\& ...)}.
3055+
Let \exposid{error-completion} be a pack consisting of
3056+
the type \tcode{set_error_t(exception_ptr)}
3057+
if \tcode{(\exposid{is-nothrow-decay-copy-sig}<Sigs> \&\&...)} is \tcode{false},
3058+
and an empty pack otherwise.
30323059
Then \tcode{variant_t} denotes
3033-
the type \tcode{variant<monostate, \exposid{as-tuple}<Sigs>...>},
3060+
the type \tcode{variant<monostate, \exposid{as-tuple}<Sigs>..., \exposid{error-completion}...>},
30343061
except with duplicate types removed.
30353062

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

30863113
try {
30873114
state.@\exposid{async-result}@.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
30883115
} catch (...) {
3089-
if constexpr (!nothrow) {
3090-
set_error(std::move(rcvr), current_exception());
3091-
return;
3092-
}
3116+
if constexpr (!nothrow)
3117+
state.@\exposid{async-result}@.template emplace<tuple<set_error_t,
3118+
exception_ptr>>(set_error, current_exception());
30933119
}
30943120
start(state.@\exposid{op-state}@);
30953121
};
@@ -3493,9 +3519,13 @@
34933519
\item
34943520
given a query object \tcode{q},
34953521
the expression \tcode{e.query(q)} is expression-equivalent
3496-
to \tcode{\exposid{env}.query(q)} if that expression is valid,
3497-
otherwise \tcode{e.query(q)} is expression-equivalent
3498-
to \tcode{get_env(\exposid{rcvr}).query(q)}.
3522+
to \tcode{\exposid{env}.query(q)} if that expression is valid;
3523+
otherwise,
3524+
if the type of \tcode{q} satisfies \exposconcept{forwarding-query},
3525+
\tcode{e.query(q)} is expression-equivalent
3526+
to \tcode{get_env(\exposid{rcvr}).query(q)};
3527+
otherwise,
3528+
\tcode{e.query(q)} is ill-formed.
34993529
\end{itemize}
35003530

35013531
\pnum
@@ -3522,7 +3552,7 @@
35223552
\pnum
35233553
Let \tcode{Sigs} be a pack of the arguments
35243554
to the \tcode{completion_signatures} specialization named by
3525-
\tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, env_of_t<Rcvr>>}.
3555+
\tcode{completion_signatures_of_t<\exposid{child-type}<Sndr>, \exposid{FWD-ENV-T}(env_of_t<Rcvr>)>}.
35263556
Let \tcode{LetSigs} be a pack of those types in \tcode{Sigs}
35273557
with a return type of \tcode{\exposid{decayed-typeof}<\exposid{set-cpo}>}.
35283558
Let \exposid{as-tuple} be an alias template
@@ -3540,7 +3570,7 @@
35403570
Then \tcode{ops2_variant_t} denotes
35413571
the type
35423572
\begin{codeblock}
3543-
variant<monostate, connect_result_t<@\exposid{as-sndr2}@<LetSigs>, @\exposid{receiver2}@<Rcvr, Env>>...>
3573+
variant<monostate, connect_result_t<@\exposid{as-sndr2}@<LetSigs>, @\exposid{receiver2}@<Rcvr, env_t>>...>
35443574
\end{codeblock}
35453575
except with duplicate types removed.
35463576

@@ -3585,8 +3615,11 @@
35853615
is \tcode{false},
35863616
then the expression \tcode{\exposid{let-cpo}.transform_env(sndr, env)}
35873617
is ill-formed.
3588-
Otherwise, it is equal to
3589-
\tcode{\exposid{JOIN-ENV}(\exposid{let-env}(sndr), \exposid{FWD-ENV}(env))}.
3618+
Otherwise, it is equal to:
3619+
\begin{codeblock}
3620+
auto& [_, _, child] = sndr;
3621+
return @\exposid{JOIN-ENV}@(@\exposid{let-env}@(child), @\exposid{FWD-ENV}@(env));
3622+
\end{codeblock}
35903623

35913624
\pnum
35923625
Let the subexpression \tcode{out_sndr} denote
@@ -4153,7 +4186,8 @@
41534186
\tcode{e.query(get_stop_token)} is expression-equivalent to
41544187
\tcode{state.\exposid{stop-src}.get_token()}, and
41554188
\item
4156-
given a query object \tcode{q} with type other than \cv{} \tcode{stop_token_t},
4189+
given a query object \tcode{q} with type other than \cv{} \tcode{stop_token_t}
4190+
and whose type satisfies \exposconceptx{forwarding-que\-ry}{forwarding-query},
41574191
\tcode{e.query(q)} is expression-equivalent to \tcode{get_env(rcvr).query(q)}.
41584192
\end{itemize}
41594193

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

41814215
template<class Rcvr>
41824216
struct @\exposid{make-state}@ {
4183-
template<@\exposconcept{max-1-sender-in}@<env_of_t<Rcvr>>... Sndrs>
4217+
template<@\exposconcept{max-1-sender-in}@<@\exposid{FWD-ENV-T}@(env_of_t<Rcvr>)>... Sndrs>
41844218
auto operator()(auto, auto, Sndrs&&... sndrs) const {
41854219
using values_tuple = @\seebelow@;
41864220
using errors_variant = @\seebelow@;
@@ -4217,7 +4251,7 @@
42174251
\pnum
42184252
The alias \tcode{values_tuple} denotes the type
42194253
\begin{codeblock}
4220-
tuple<value_types_of_t<Sndrs, env_of_t<Rcvr>, @\exposid{decayed-tuple}@, optional>...>
4254+
tuple<value_types_of_t<Sndrs, @\exposid{FWD-ENV-T}@(env_of_t<Rcvr>), @\exposid{decayed-tuple}@, optional>...>
42214255
\end{codeblock}
42224256
if that type is well-formed; otherwise, \tcode{tuple<>}.
42234257

@@ -4405,7 +4439,7 @@
44054439
is initialized with a callable object equivalent to the following lambda:
44064440
\begin{codeblock}
44074441
[]<class Sndr, class Rcvr>(Sndr&& sndr, Rcvr& rcvr) noexcept
4408-
-> type_identity<value_types_of_t<@\exposid{child-type}@<Sndr>, env_of_t<Rcvr>>> {
4442+
-> type_identity<value_types_of_t<@\exposid{child-type}@<Sndr>, @\exposid{FWD-ENV-T}@(env_of_t<Rcvr>)>> {
44094443
return {};
44104444
}
44114445
\end{codeblock}
@@ -4450,14 +4484,14 @@
44504484
\tcode{Env} is \tcode{decltype((env))}.
44514485
If \tcode{\exposconcept{sender-for}<Sndr, stopped_as_optional_t>}
44524486
is \tcode{false}, or
4453-
if the type \tcode{\exposid{single-sender-value-type}<Sndr, Env>}
4487+
if the type \tcode{\exposid{single-sender-value-type}<\linebreak{}\exposid{child-type}<Sndr>, \exposid{FWD-ENV-T}(Env)>}
44544488
is ill-formed or \tcode{void},
4455-
then the expression \tcode{stopped_as_optional.transform_sender(sndr, env)}
4489+
then the expression \tcode{stopped_as_optional.\linebreak{}transform_sender(sndr, env)}
44564490
is ill-formed;
44574491
otherwise, it is equivalent to:
44584492
\begin{codeblock}
44594493
auto&& [_, _, child] = sndr;
4460-
using V = @\exposid{single-sender-value-type}@<Sndr, Env>;
4494+
using V = @\exposid{single-sender-value-type}@<@\exposid{child-type}@<Sndr>, @\exposid{FWD-ENV-T}@(Env)>;
44614495
return let_stopped(
44624496
then(std::forward_like<Sndr>(child),
44634497
[]<class... Ts>(Ts&&... ts) noexcept(is_nothrow_constructible_v<V, Ts...>) {

source/iostreams.tex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6257,7 +6257,8 @@
62576257
is
62586258
\tcode{true},
62596259
calls
6260-
\tcode{os.rdbuf()->pubsync()}. If that function returns $-1$, sets \tcode{badbit} in
6260+
\tcode{os.rdbuf()->pubsync()}. If that function returns $-1$ or
6261+
exits via an exception, sets \tcode{badbit} in
62616262
\tcode{os.rdstate()} without propagating an exception.
62626263
\end{itemdescr}
62636264

source/iterators.tex

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3068,7 +3068,13 @@
30683068
\begin{itemdescr}
30693069
\pnum
30703070
\effects
3071-
Equivalent to: \tcode{return last - static_cast<const decay_t<I>\&>(first);}
3071+
Equivalent to:
3072+
\begin{codeblock}
3073+
if constexpr (!is_array_v<remove_reference_t<I>>)
3074+
return last - first;
3075+
else
3076+
return last - static_cast<decay_t<I>>(first);
3077+
\end{codeblock}
30723078
\end{itemdescr}
30733079

30743080
\indexlibraryglobal{distance}%
@@ -5965,9 +5971,9 @@
59655971
friend constexpr iter_difference_t<I2> operator-(
59665972
const counted_iterator& x, const counted_iterator<I2>& y);
59675973
friend constexpr iter_difference_t<I> operator-(
5968-
const counted_iterator& x, default_sentinel_t);
5974+
const counted_iterator& x, default_sentinel_t) noexcept;
59695975
friend constexpr iter_difference_t<I> operator-(
5970-
default_sentinel_t, const counted_iterator& y);
5976+
default_sentinel_t, const counted_iterator& y) noexcept;
59715977
constexpr counted_iterator& operator-=(iter_difference_t<I> n)
59725978
requires @\libconcept{random_access_iterator}@<I>;
59735979

@@ -5978,7 +5984,7 @@
59785984
friend constexpr bool operator==(
59795985
const counted_iterator& x, const counted_iterator<I2>& y);
59805986
friend constexpr bool operator==(
5981-
const counted_iterator& x, default_sentinel_t);
5987+
const counted_iterator& x, default_sentinel_t) noexcept;
59825988

59835989
template<@\libconcept{common_with}@<I> I2>
59845990
friend constexpr strong_ordering operator<=>(
@@ -6309,7 +6315,7 @@
63096315
\indexlibrarymember{operator-}{counted_iterator}%
63106316
\begin{itemdecl}
63116317
friend constexpr iter_difference_t<I> operator-(
6312-
const counted_iterator& x, default_sentinel_t);
6318+
const counted_iterator& x, default_sentinel_t) noexcept;
63136319
\end{itemdecl}
63146320

63156321
\begin{itemdescr}
@@ -6322,7 +6328,7 @@
63226328
\indexlibrarymember{operator-}{counted_iterator}%
63236329
\begin{itemdecl}
63246330
friend constexpr iter_difference_t<I> operator-(
6325-
default_sentinel_t, const counted_iterator& y);
6331+
default_sentinel_t, const counted_iterator& y) noexcept;
63266332
\end{itemdecl}
63276333

63286334
\begin{itemdescr}
@@ -6375,7 +6381,7 @@
63756381
\indexlibrarymember{operator==}{counted_iterator}%
63766382
\begin{itemdecl}
63776383
friend constexpr bool operator==(
6378-
const counted_iterator& x, default_sentinel_t);
6384+
const counted_iterator& x, default_sentinel_t) noexcept;
63796385
\end{itemdecl}
63806386

63816387
\begin{itemdescr}
@@ -7243,6 +7249,7 @@
72437249
\libheaderrefx{flat_map}{flat.map.syn},
72447250
\libheaderrefx{flat_set}{flat.set.syn},
72457251
\libheaderrefx{forward_list}{forward.list.syn},
7252+
\libheaderref{hive},
72467253
\libheaderrefx{inplace_vector}{inplace.vector.syn},
72477254
\libheaderref{list},
72487255
\libheaderrefx{map}{associative.map.syn},

source/lib-intro.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,7 @@
16301630
\ref{expected} & Expected objects & \tcode{<expected>} \\ \rowsep
16311631
\ref{function.objects} & Function objects & \tcode{<functional>} \\ \rowsep
16321632
\ref{bit} & Bit manipulation & \tcode{<bit>} \\ \rowsep
1633+
\ref{stdbit.h.syn} & C-compatible bit manipulation & \tcode{<stdbit.h>} \\ \rowsep
16331634
\ref{array} & Class template \tcode{array} & \tcode{<array>} \\ \rowsep
16341635
\ref{inplace.vector} & Class template \tcode{inplace_vector} & \tcode{<inplace_vector>} \\ \rowsep
16351636
\ref{views.contiguous} & Contiguous access & \tcode{<span>} \\ \rowsep

0 commit comments

Comments
 (0)