From 87365918b80445eac2a2d91d4cee873b017dd365 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 15 Nov 2025 11:02:59 +1100 Subject: [PATCH 01/54] LWG3343 Ordering of calls to unlock() and notify_all() in Effects element of notify_all_at_thread_exit() should be reversed --- source/threads.tex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/threads.tex b/source/threads.tex index f4b4f462d0..089a0ea4f7 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -9504,11 +9504,14 @@ \effects Transfers ownership of the lock associated with \tcode{lk} into internal storage and schedules \tcode{cond} to be notified when the current -thread exits, after all objects with thread storage duration associated with -the current thread have been destroyed. This notification is equivalent to: +thread exits. +This notification is sequenced after +all objects with thread storage duration associated with +the current thread have been destroyed and +is equivalent to: \begin{codeblock} -lk.unlock(); cond.notify_all(); +lk.unlock(); \end{codeblock} \pnum From e05ab3c2216d35593a0755ae3fd913b5fd1532c5 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Sat, 15 Nov 2025 11:16:15 +1100 Subject: [PATCH 02/54] LWG3454 pointer_traits::pointer_to should be constexpr [pointer.traits] Note: declaration of pointer_to in synopsis was removed in LWG3545. --- source/memory.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 8243d4ab32..f87be79829 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -846,7 +846,7 @@ \indexlibrarymember{pointer_to}{pointer_traits}% \begin{itemdecl} -static pointer pointer_traits::pointer_to(@\seebelow@ r); +static constexpr pointer pointer_traits::pointer_to(@\seebelow@ r); static constexpr pointer pointer_traits::pointer_to(@\seebelow@ r) noexcept; \end{itemdecl} From 1ff64a84384aee6f3bde92122e144fcf54d9b1a6 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 14:40:33 -0800 Subject: [PATCH 03/54] LWG4015 LWG 3973 broke const overloads of std::optional monadic operations --- source/utilities.tex | 183 +++++++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 86 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 8fe2a3ade6..0335476973 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -3362,7 +3362,9 @@ constexpr void reset() noexcept; private: - T* @\exposidnc{val}@; // \expos + union { + remove_cv_t @\exposidnc{val}@; // \expos + }; }; template @@ -3371,19 +3373,14 @@ \end{codeblock} \pnum -An object of type \tcode{optional} at any given time -either contains a value or does not contain a value. -When an object of type \tcode{optional} -\defnx{contains a value}{contains a value!\idxcode{optional}}, -it means that an object of type \tcode{T}, referred to as the optional object's \defnx{contained value}{contained value!\idxcode{optional}}, +An instance of \tcode{optional} is said to +\defnx{contain a value}{contain a value!\idxcode{optional}} +when and only when +its member \exposid{val} is active\iref{class.union.general}; +\exposid{val} is referred to as its +\defnx{contained value}{contained value!\idxcode{optional}}. +An optional object's contained value is nested within\iref{intro.object} the optional object. -When an object of type \tcode{optional} is contextually converted to \tcode{bool}, -the conversion returns \tcode{true} if the object contains a value; -otherwise the conversion returns \tcode{false}. - -\pnum -When an object of type \tcode{optional} contains a value, -member \tcode{val} points to the contained value. \pnum A type \tcode{X} is a @@ -3434,8 +3431,8 @@ \begin{itemdescr} \pnum \effects -If \tcode{rhs} contains a value, direct-non-list-initializes the contained value -with \tcode{*rhs}. +If \tcode{rhs} contains a value, direct-non-list-initializes \exposid{val} +with \tcode{rhs.\exposid{val}}. \pnum \ensures @@ -3465,8 +3462,8 @@ \pnum \effects -If \tcode{rhs} contains a value, direct-non-list-initializes the contained value -with \tcode{*std::move(rhs)}. +If \tcode{rhs} contains a value, direct-non-list-initializes \exposid{val} +with \tcode{std::move(rhs.\exposid{val})}. \tcode{rhs.has_value()} is unchanged. \pnum @@ -3497,7 +3494,8 @@ \pnum \effects -Direct-non-list-initializes the contained value with \tcode{std::forward(args)...}. +Direct-non-list-initializes \exposid{val} +with \tcode{std::forward(args)...}. \pnum \ensures @@ -3525,7 +3523,8 @@ \pnum \effects -Direct-non-list-initializes the contained value with \tcode{il, std::forward(args)...}. +Direct-non-list-initializes \exposid{val} +with \tcode{il, std::forward(args)...}. \pnum \ensures @@ -3558,7 +3557,8 @@ \pnum \effects -Direct-non-list-initializes the contained value with \tcode{std::forward(v)}. +Direct-non-list-initializes \exposid{val} +with \tcode{std::forward(v)}. \pnum \ensures @@ -3595,7 +3595,8 @@ \pnum \effects If \tcode{rhs} contains a value, -direct-non-list-initializes the contained value with \tcode{*rhs}. +direct-non-list-initializes \exposid{val} +with \tcode{rhs.operator*()}. \pnum \ensures @@ -3630,7 +3631,8 @@ \pnum \effects If \tcode{rhs} contains a value, -direct-non-list-initializes the contained value with \tcode{*std::move(rhs)}. +direct-non-list-initializes \exposid{val} +with \tcode{std::move(rhs).operator*()}. \tcode{rhs.has_value()} is unchanged. \pnum @@ -3659,10 +3661,10 @@ \begin{itemdescr} \pnum \effects -If \tcode{is_trivially_destructible_v != true} and \tcode{*this} contains a value, calls -\begin{codeblock} -val->T::~T() -\end{codeblock} +%%FIXME: Do we want "is \tcode{false}" here instead? +If \tcode{is_trivially_destructible_v != true} is \tcode{true} +and \tcode{*this} contains a value, +calls \tcode{\exposid{val}.T::\~T()}. \pnum \remarks @@ -3679,7 +3681,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{*this} contains a value, calls \tcode{val->T::\~T()} to destroy the contained value; otherwise no effect. +If \tcode{*this} contains a value, calls \tcode{\exposid{val}.T::\~T()} to destroy the contained value; otherwise no effect. \pnum \ensures @@ -3704,12 +3706,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{*rhs} to the contained value & -direct-non-list-initializes the contained value with \tcode{*rhs} \\ +assigns \tcode{rhs.\exposid{val}} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{rhs.\exposid{val}} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3756,12 +3758,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{*std::move(rhs)} to the contained value & -direct-non-list-initializes the contained value with \tcode{*std::move(rhs)} \\ +assigns \tcode{std::move(rhs.\exposid{val})} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{std::move(rhs.\exposid{val})} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3783,9 +3785,9 @@ \pnum If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s move constructor, -the state of \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{T}'s move constructor. +the state of \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{T}'s move constructor. If an exception is thrown during the call to \tcode{T}'s move assignment, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{T}'s move assignment. +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s move assignment. If \tcode{is_trivially_move_constructible_v \&\&} \tcode{is_trivially_move_assignable_v \&\&} \tcode{is_trivially_destructible_v} is \tcode{true}, @@ -3809,7 +3811,10 @@ \pnum \effects -If \tcode{*this} contains a value, assigns \tcode{std::forward(v)} to the contained value; otherwise direct-non-list-initializes the contained value with \tcode{std::forward(v)}. +If \tcode{*this} contains a value, +assigns \tcode{std::forward(v)} to \exposid{val}; +otherwise direct-non-list-initializes \exposid{val} +with \tcode{std::forward(v)}. \pnum \ensures @@ -3821,7 +3826,9 @@ \pnum \remarks -If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, the state of \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, the state of \tcode{*val} and \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s assignment. +If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, the state of \tcode{v} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, +the states of \exposid{val} and \tcode{v} are +determined by the exception safety guarantee of \tcode{T}'s assignment. \end{itemdescr} \indexlibrarymember{operator=}{optional}% @@ -3850,12 +3857,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{*rhs} to the contained value & -direct-non-list-initializes the contained value with \tcode{*rhs} \\ +assigns \tcode{rhs.operator*()} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{rhs.operator*()} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3872,10 +3879,10 @@ If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, -the state of \tcode{*rhs.val} is determined by +the state of \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s assignment. \end{itemdescr} @@ -3906,12 +3913,12 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -assigns \tcode{*std::move(rhs)} to the contained value & -direct-non-list-initializes the contained value with \tcode{*std::move(rhs)} \\ +assigns \tcode{std::move(rhs).op\-erator*()} to \exposid{val} & +direct-non-list-initializes \exposid{val} with \tcode{std::move(rhs).opera\-tor*()} \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -destroys the contained value by calling \tcode{val->T::\~T()} & +destroys the contained value by calling \tcode{\exposid{val}.T::\~T()} & no effect \\ \end{lib2dtab2} @@ -3928,10 +3935,10 @@ If any exception is thrown, the result of the expression \tcode{this->has_value()} remains unchanged. If an exception is thrown during the call to \tcode{T}'s constructor, -the state of \tcode{*rhs.val} is determined by +the state of \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{T}'s constructor. If an exception is thrown during the call to \tcode{T}'s assignment, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s assignment. \end{itemdescr} @@ -3947,8 +3954,8 @@ \pnum \effects -Calls \tcode{*this = nullopt}. Then direct-non-list-initializes the contained value -with \tcode{std::forward\brk{}(args)...}. +Calls \tcode{*this = nullopt}. Then direct-non-list-initializes \exposid{val} +with \tcode{std::forward(args\brk{})...}. \pnum \ensures @@ -3956,7 +3963,7 @@ \pnum \returns -A reference to the new contained value. +\exposid{val}. \pnum \throws @@ -3964,7 +3971,9 @@ \pnum \remarks -If an exception is thrown during the call to \tcode{T}'s constructor, \tcode{*this} does not contain a value, and the previous \tcode{*val} (if any) has been destroyed. +If an exception is thrown during the call to \tcode{T}'s constructor, +\tcode{*this} does not contain a value, and +the previous \exposid{val} (if any) has been destroyed. \end{itemdescr} \indexlibrarymember{emplace}{optional}% @@ -3979,8 +3988,8 @@ \pnum \effects -Calls \tcode{*this = nullopt}. Then direct-non-list-initializes the contained value with -\tcode{il, std::\brk{}forward(args)...}. +Calls \tcode{*this = nullopt}. Then direct-non-list-initializes \exposid{val} with +\tcode{il, std::forward(\brk{}args)...}. \pnum \ensures @@ -3988,7 +3997,7 @@ \pnum \returns -A reference to the new contained value. +\exposid{val}. \pnum \throws @@ -3996,7 +4005,9 @@ \pnum \remarks -If an exception is thrown during the call to \tcode{T}'s constructor, \tcode{*this} does not contain a value, and the previous \tcode{*val} (if any) has been destroyed. +If an exception is thrown during the call to \tcode{T}'s constructor, +\tcode{*this} does not contain a value, and +the previous \exposid{val} (if any) has been destroyed. \end{itemdescr} \rSec3[optional.swap]{Swap} @@ -4023,17 +4034,17 @@ {\tcode{*this} does not contain a value} \rowhdr{\tcode{rhs} contains a value} & -calls \tcode{swap(*(*this), *rhs)} & -direct-non-list-initializes the contained value of \tcode{*this} -with \tcode{std::move(*rhs)}, -followed by \tcode{rhs.val->T::\~T()}; +calls \tcode{swap(\exposid{val}, rhs.\exposid{val})} & +direct-non-list-initializes \exposid{val} +with \tcode{std::move(rhs.\exposid{val})}, +followed by \tcode{rhs.\exposid{val}.T::\~T()}; postcondition is that \tcode{*this} contains a value and \tcode{rhs} does not contain a value \\ \rowsep \rowhdr{\tcode{rhs} does not contain a value} & -direct-non-list-initializes the contained value of \tcode{rhs} -with \tcode{std::move(*(*this))}, -followed by \tcode{val->T::\~T()}; +direct-non-list-initializes \tcode{rhs.\exposid{val}} +with \tcode{std::move(\exposid{val})}, +followed by \tcode{\exposid{val}.T::\~T()}; postcondition is that \tcode{*this} does not contain a value and \tcode{rhs} contains a value & no effect \\ \end{lib2dtab2} @@ -4052,9 +4063,9 @@ \pnum If any exception is thrown, the results of the expressions \tcode{this->has_value()} and \tcode{rhs.has_value()} remain unchanged. If an exception is thrown during the call to function \tcode{swap}, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{swap} for lvalues of \tcode{T}. +the state of \exposid{val} and \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{swap} for lvalues of \tcode{T}. If an exception is thrown during the call to \tcode{T}'s move constructor, -the state of \tcode{*val} and \tcode{*rhs.val} is determined by the exception safety guarantee of \tcode{T}'s move constructor. +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s move constructor. \end{itemdescr} \rSec3[optional.iterators]{Iterator support} @@ -4125,7 +4136,7 @@ \pnum \returns -\tcode{val}. +\tcode{addressof(\exposid{val})}. \pnum \remarks @@ -4145,7 +4156,7 @@ \pnum \returns -\tcode{*val}. +\exposid{val}. \pnum \remarks @@ -4165,7 +4176,7 @@ \pnum \effects -Equivalent to: \tcode{return std::move(*val);} +Equivalent to: \tcode{return std::move(\exposid{val});} \end{itemdescr} \indexlibrarymember{operator bool}{optional}% @@ -4209,7 +4220,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? *val : throw bad_optional_access(); +return has_value() ? @\exposid{val}@ : throw bad_optional_access(); \end{codeblock} \end{itemdescr} @@ -4225,7 +4236,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? std::move(*val) : throw bad_optional_access(); +return has_value() ? std::move(@\exposid{val}@) : throw bad_optional_access(); \end{codeblock} \end{itemdescr} @@ -4243,7 +4254,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? **this : static_cast(std::forward(v)); +return has_value() ? @\exposid{val}@ : static_cast(std::forward(v)); \end{codeblock} \end{itemdescr} @@ -4261,7 +4272,7 @@ \effects Equivalent to: \begin{codeblock} -return has_value() ? std::move(**this) : static_cast(std::forward(v)); +return has_value() ? std::move(@\exposid{val}@) : static_cast(std::forward(v)); \end{codeblock} \end{itemdescr} @@ -4275,7 +4286,7 @@ \begin{itemdescr} \pnum -Let \tcode{U} be \tcode{invoke_result_t}. +Let \tcode{U} be \tcode{invoke_result_t}. \pnum \mandates @@ -4286,7 +4297,7 @@ Equivalent to: \begin{codeblock} if (*this) { - return invoke(std::forward(f), *@\exposid{val}@); + return invoke(std::forward(f), @\exposid{val}@); } else { return remove_cvref_t(); } @@ -4301,7 +4312,7 @@ \begin{itemdescr} \pnum -Let \tcode{U} be \tcode{invoke_result_t}. +Let \tcode{U} be \tcode{invoke_result_t}. \pnum \mandates @@ -4312,7 +4323,7 @@ Equivalent to: \begin{codeblock} if (*this) { - return invoke(std::forward(f), std::move(*@\exposid{val}@)); + return invoke(std::forward(f), std::move(@\exposid{val}@)); } else { return remove_cvref_t(); } @@ -4327,14 +4338,14 @@ \begin{itemdescr} \pnum -Let \tcode{U} be \tcode{remove_cv_t>}. +Let \tcode{U} be \tcode{remove_cv_t>}. \pnum \mandates \tcode{U} is a valid contained type for \tcode{optional}. The declaration \begin{codeblock} -U u(invoke(std::forward(f), *@\exposid{val}@)); +U u(invoke(std::forward(f), @\exposid{val}@)); \end{codeblock} is well-formed for some invented variable \tcode{u}. \begin{note} @@ -4345,7 +4356,7 @@ \returns If \tcode{*this} contains a value, an \tcode{optional} object whose contained value is direct-non-list-initialized with -\tcode{invoke(std::forward(f), *\exposid{val})}; +\tcode{invoke(std::forward(f), \exposid{val})}; otherwise, \tcode{optional()}. \end{itemdescr} @@ -4358,14 +4369,14 @@ \begin{itemdescr} \pnum Let \tcode{U} be -\tcode{remove_cv_t>}. +\tcode{remove_cv_t>}. \pnum \mandates \tcode{U} is a valid contained type for \tcode{optional}. The declaration \begin{codeblock} -U u(invoke(std::forward(f), std::move(*@\exposid{val}@))); +U u(invoke(std::forward(f), std::move(@\exposid{val}@))); \end{codeblock} is well-formed for some invented variable \tcode{u}. \begin{note} @@ -4376,7 +4387,7 @@ \returns If \tcode{*this} contains a value, an \tcode{optional} object whose contained value is direct-non-list-initialized with -\tcode{invoke(std::forward(f), std::move(*\exposid{val}))}; +\tcode{invoke(std::forward(f), std::move(\exposid{val}))}; otherwise, \tcode{optional()}. \end{itemdescr} @@ -4444,7 +4455,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{*this} contains a value, calls \tcode{val->T::\~T()} to destroy the contained value; +If \tcode{*this} contains a value, calls \tcode{\exposid{val}.T::\~T()} to destroy the contained value; otherwise no effect. \pnum @@ -4607,7 +4618,7 @@ \effects Equivalent to: \begin{codeblock} -if (rhs.has_value()) @\exposid{convert-ref-init-val}@(*rhs); +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(rhs.operator*()); \end{codeblock} \pnum @@ -4638,7 +4649,7 @@ \effects Equivalent to: \begin{codeblock} -if (rhs.has_value()) @\exposid{convert-ref-init-val}@(*rhs); +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(rhs.operator*()); \end{codeblock} \pnum @@ -4669,7 +4680,7 @@ \effects Equivalent to: \begin{codeblock} -if (rhs.has_value()) @\exposid{convert-ref-init-val}@(*std::move(rhs)); +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(std::move(rhs).operator*()); \end{codeblock} \pnum @@ -4700,7 +4711,7 @@ \effects Equivalent to: \begin{codeblock} -if (rhs.has_value()) @\exposid{convert-ref-init-val}@(*std::move(rhs)); +if (rhs.has_value()) @\exposid{convert-ref-init-val}@(std::move(rhs).operator*()); \end{codeblock} \pnum From c14d86f6c4bdccd0454efa0d94f8fe15e5a0f727 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 23:47:53 -0800 Subject: [PATCH 04/54] [optional.dtor] Fix double negative in wording added by LWG4015. --- source/utilities.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index 0335476973..8798c64409 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -3661,8 +3661,7 @@ \begin{itemdescr} \pnum \effects -%%FIXME: Do we want "is \tcode{false}" here instead? -If \tcode{is_trivially_destructible_v != true} is \tcode{true} +If \tcode{is_trivially_destructible_v} is \tcode{false} and \tcode{*this} contains a value, calls \tcode{\exposid{val}.T::\~T()}. From 447d66df018689f91a5fc611b2cd82d1c3dacccf Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Thu, 4 Dec 2025 00:04:25 -0800 Subject: [PATCH 05/54] [optional.swap] Fix singular->plural tense that was missed in LWG4015. --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index 8798c64409..9c6390be1b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -4062,7 +4062,7 @@ \pnum If any exception is thrown, the results of the expressions \tcode{this->has_value()} and \tcode{rhs.has_value()} remain unchanged. If an exception is thrown during the call to function \tcode{swap}, -the state of \exposid{val} and \tcode{rhs.\exposid{val}} is determined by the exception safety guarantee of \tcode{swap} for lvalues of \tcode{T}. +the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{swap} for lvalues of \tcode{T}. If an exception is thrown during the call to \tcode{T}'s move constructor, the states of \exposid{val} and \tcode{rhs.\exposid{val}} are determined by the exception safety guarantee of \tcode{T}'s move constructor. \end{itemdescr} From b16e1a5974aa7d72977384b395d9b18b911aab37 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 18:58:16 -0800 Subject: [PATCH 06/54] LWG4230 simd::real/imag is overconstrained --- source/numerics.tex | 61 ++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 609aa6e733..99294d8b78 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -17541,6 +17541,7 @@ \begin{codeblock} namespace std::simd { template class basic_vec { + using @\exposid{real-type}@ = @\seebelow@; // \expos public: using @\libmember{value_type}{basic_vec}@ = T; using @\libmember{mask_type}{basic_vec}@ = basic_mask; @@ -17569,8 +17570,7 @@ constexpr basic_vec(R&& range, flags = {}); template constexpr basic_vec(R&& range, const mask_type& mask, flags = {}); - template<@\exposconcept{simd-floating-point}@ V> - constexpr explicit(@\seebelow@) basic_vec(const V& reals, const V& imags = {}) noexcept; + constexpr basic_vec(const @\exposid{real-type}@& reals, const @\exposid{real-type}@& imags = {}) noexcept; // \ref{simd.subscr}, \tcode{basic_vec} subscript operators constexpr value_type operator[](@\exposid{simd-size-type}@) const; @@ -17578,12 +17578,10 @@ constexpr resize_t operator[](const I& indices) const; // \ref{simd.complex.access}, \tcode{basic_vec} complex accessors - constexpr auto real() const noexcept; - constexpr auto imag() const noexcept; - template<@\exposconcept{simd-floating-point}@ V> - constexpr void real(const V& v) noexcept; - template<@\exposconcept{simd-floating-point}@ V> - constexpr void imag(const V& v) noexcept; + constexpr @\exposid{real-type}@ real() const noexcept; + constexpr @\exposid{real-type}@ imag() const noexcept; + constexpr void real(const @\exposid{real-type}@& v) noexcept; + constexpr void imag(const @\exposid{real-type}@& v) noexcept; // \ref{simd.unary}, \tcode{basic_vec} unary operators constexpr basic_vec& operator++() noexcept; @@ -17677,6 +17675,12 @@ implementation. \end{note} +\pnum +If \tcode{T} is a specialization of \tcode{complex}, +\exposid{real-type} denotes the same type as +\tcode{rebind_t>}, +otherwise an unspecified non-array object type. + \rSec3[simd.ctor]{Constructors} \indexlibraryctor{basic_vec} @@ -17856,31 +17860,18 @@ \indexlibraryctor{basic_vec} \begin{itemdecl} -template<@\exposconcept{simd-floating-point}@ V> - constexpr explicit(@\seebelow@) - basic_vec(const V& reals, const V& imags = {}) noexcept; +constexpr basic_vec(const @\exposid{real-type}@& reals, const @\exposid{real-type}@& imags = {}) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints -\begin{itemize} - \item - \tcode{\exposconcept{simd-complex}} is modeled, and - \item - \tcode{V::size() == size()} is \tcode{true}. -\end{itemize} +\tcode{\exposconcept{simd-complex}} is modeled. \pnum \effects Initializes the $i^\text{th}$ element with \tcode{value_type(reals[$i$], imags[$i$])} for all $i$ in the range \range{0}{size()}. - -\pnum -\remarks -The expression inside \tcode{explicit} evaluates to \tcode{false} if and only -if the floating-point conversion rank of \tcode{T::value_type} is greater than -or equal to the floating-point conversion rank of \tcode{V::value_type}. \end{itemdescr} \rSec3[simd.subscr]{Subscript operator} @@ -17921,8 +17912,8 @@ \indexlibrarymember{real}{basic_vec} \indexlibrarymember{imag}{basic_vec} \begin{itemdecl} -constexpr auto real() const noexcept; -constexpr auto imag() const noexcept; +constexpr @\exposid{real-type}@ real() const noexcept; +constexpr @\exposid{real-type}@ imag() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -17932,9 +17923,9 @@ \pnum \returns -An object of type \tcode{rebind_t} +An object of type \exposid{real-type} where the $i^\text{th}$ element is initialized to the result of -\tcode{\placeholder{cmplx-func}(operator[]($i$))} for all $i$ in the range +\tcode{\placeholder{cmplx-func}(\brk{}operator[]($i$))} for all $i$ in the range \range{0}{size()}, where \tcode{\placeholder{cmplx-func}} is the corresponding function from \libheader{complex}. \end{itemdescr} @@ -17942,24 +17933,14 @@ \indexlibrarymember{real}{basic_vec} \indexlibrarymember{imag}{basic_vec} \begin{itemdecl} -template<@\exposconcept{simd-floating-point}@ V> - constexpr void real(const V& v) noexcept; -template<@\exposconcept{simd-floating-point}@ V> - constexpr void imag(const V& v) noexcept; +constexpr void real(const @\exposid{real-type}@& v) noexcept; +constexpr void imag(const @\exposid{real-type}@& v) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints -\begin{itemize} - \item - \tcode{\exposconcept{simd-complex}} is modeled, - \item - \tcode{\libconcept{same_as}} - is modeled, and - \item - \tcode{V::size() == size()} is \tcode{true}. -\end{itemize} +\tcode{\exposconcept{simd-complex}} is modeled. \pnum \effects From 21fc91878346ff2278a7aeb57dec255468788855 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 20:10:25 -0800 Subject: [PATCH 07/54] LWG4251 Move assignment for indirect unnecessarily requires copy construction --- source/memory.tex | 50 ++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/source/memory.tex b/source/memory.tex index f87be79829..09416c774b 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -6315,7 +6315,11 @@ \begin{itemdescr} \pnum \mandates -\tcode{is_copy_constructible_v} is \tcode{true}. +If +\tcode{allocator_traits::propagate_on_container_move_assignment::val\-ue} +is \tcode{false} and +\tcode{allocator_traits::is_always_equal::value} is \tcode{false}, +\tcode{is_move_con\-structible_v} is \tcode{true}. \pnum \effects @@ -6332,28 +6336,20 @@ \item If \tcode{other} is valueless, -\tcode{*this} becomes valueless and -the owned object in \tcode{*this}, if any, -is destroyed using \tcode{allocator_traits::destroy} and -then the storage is deallocated. +\tcode{*this} becomes valueless. \item Otherwise, +if the allocator needs updating or if \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, -swaps the owned objects in \tcode{*this} and \tcode{other}; -the owned object in \tcode{other}, if any, -is then destroyed using \tcode{allocator_traits::destroy} and -then the storage is deallocated. +\tcode{*this} takes ownership of the owned object of \tcode{other}. \item Otherwise, constructs a new owned object with %FIXME: "as the argument as an rvalue" is awkward. the owned object of \tcode{other} as the argument as an rvalue, -using either -the allocator in \tcode{*this} or -the allocator in \tcode{other} -if the allocator needs updating. +using the allocator in \tcode{*this}. \item The previously owned object in \tcode{*this}, if any, @@ -7164,7 +7160,10 @@ \begin{itemdescr} \pnum \mandates -If \tcode{allocator_traits::is_always_equal::value} is \tcode{false}, +If +\tcode{allocator_traits::propagate_on_container_move_assignment::val\-ue} +is \tcode{false} and +\tcode{allocator_traits::is_always_equal::value} is \tcode{false}, \tcode{T} is a complete type. \pnum @@ -7181,22 +7180,19 @@ is \tcode{true}. \item -If \tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, -swaps the owned objects in \tcode{*this} and \tcode{other}; -the owned object in \tcode{other}, if any, -is then destroyed using \tcode{allocator_traits::destroy} and -then the storage is deallocated. +If \tcode{other} is valueless, \tcode{*this} becomes valueless. \item Otherwise, -if \tcode{\exposid{alloc} != other.\exposid{alloc}} is \tcode{true}; -if \tcode{other} is not valueless, -a new owned object is constructed in \tcode{*this} -using \tcode{allocator_traits::construct} with -%FIXME: Cleanup wording. -the owned object from \tcode{other} as the argument as an rvalue, -using either the allocator in \tcode{*this} or -the allocator in \tcode{other} if the allocator needs updating. +if the allocator needs updating or +\tcode{\exposid{alloc} == other.\exposid{alloc}} is \tcode{true}, +\tcode{*this} takes ownership of the owned object of \tcode{other}. + +\item +Otherwise, +constructs a new owned object with the owned object of +\tcode{other} as the argument as an rvalue, +using the allocator in \tcode{*this}. \item The previously owned object in \tcode{*this}, if any, From 008628d75a35c6459d7f8aa9b6a98f602ea3e8cb Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 20:15:26 -0800 Subject: [PATCH 08/54] LWG4260 Query objects must be default constructible --- source/lib-intro.tex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 17abe7c385..6dd34abd3d 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -871,7 +871,12 @@ \pnum The type of a customization point object, ignoring cv-qualifiers, shall model -\libconcept{semiregular}\iref{concepts.object}. +\libconcept{semiregular}\iref{concepts.object} +and shall be +a structural type\iref{temp.param} and +a trivially copyable type\iref{class.prop}. +Every constructor of this type +shall have a non-throwing exception specification\iref{except.spec}. \pnum All instances of a specific customization point object type shall From 3bb1658023104b6e05ba50324fc1275b91505802 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 20:48:56 -0800 Subject: [PATCH 09/54] LWG4272 For rank == 0, layout_stride is atypically convertible --- source/containers.tex | 46 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index f2c98aeeb7..57d7cc1a5b 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -21963,7 +21963,7 @@ extents_type>) mapping(const LayoutLeftPaddedMapping&) noexcept; template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&); constexpr mapping& operator=(const mapping&) noexcept = default; @@ -22139,7 +22139,7 @@ \indexlibraryctor{layout_left::mapping}% \begin{itemdecl} template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other); \end{itemdecl} @@ -22164,6 +22164,13 @@ \pnum \effects Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(extents_type::rank() == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \rSec5[mdspan.layout.left.obs]{Observers} @@ -22285,7 +22292,7 @@ extents_type>) mapping(const LayoutRightPaddedMapping&) noexcept; template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; @@ -22465,7 +22472,7 @@ \indexlibraryctor{layout_right::mapping}% \begin{itemdecl} template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other) noexcept; \end{itemdecl} @@ -22490,6 +22497,13 @@ \pnum \effects Direct-non-list-initializes \exposid{extents_} with \tcode{other.extents()}. + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(extents_type::rank() == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \rSec5[mdspan.layout.right.obs]{Observers} @@ -23017,7 +23031,7 @@ constexpr explicit(!is_convertible_v) mapping(const layout_left::mapping&); template - constexpr explicit(extents_type::rank() > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&); template constexpr explicit(@\seebelow@) @@ -23307,7 +23321,7 @@ \indexlibraryctor{layout_left_padded::mapping}% \begin{itemdecl} template - constexpr explicit(rank_ > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other); \end{itemdecl} @@ -23352,6 +23366,13 @@ direct-non-list-initializes \exposid{stride-1} with \tcode{other.stride(1)}. \end{itemize} + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(rank_ == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \indexlibraryctor{layout_left_padded::mapping}% @@ -23414,6 +23435,7 @@ \remarks The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} +!is_convertible_v || rank_> 1 && (padding_value != dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent) @@ -23642,7 +23664,7 @@ constexpr explicit(!is_convertible_v) mapping(const layout_right::mapping&); template - constexpr explicit(rank_ > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping&); template constexpr explicit(@\seebelow@) @@ -23936,7 +23958,7 @@ \indexlibraryctor{layout_right_padded::mapping}% \begin{itemdecl} template - constexpr explicit(rank_ > 0) + constexpr explicit(@\seebelow@) mapping(const layout_stride::mapping& other); \end{itemdecl} @@ -23982,6 +24004,13 @@ direct-non-list-initializes \exposid{stride-rm2} with \tcode{other.stride(\exposid{rank_} - 2)}. \end{itemize} + +\pnum +\remarks +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!(rank_ == 0 && is_convertible_v) +\end{codeblock} \end{itemdescr} \indexlibraryctor{layout_right_padded::mapping}% @@ -24044,6 +24073,7 @@ \remarks The expression inside \tcode{explicit} is equivalent to: \begin{codeblock} +!is_convertible_v || @\exposid{rank_}@ > 1 && (padding_value != dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent) From 0e1d4dac6fb032359f9f34c220f33d27b787f6c5 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 20:53:06 -0800 Subject: [PATCH 10/54] LWG4302 Problematic vector_sum_of_squares wording Fixes NB US 169-276 (C++26 CD). --- source/numerics.tex | 68 --------------------------------------------- 1 file changed, 68 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 99294d8b78..5a185aefe4 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -11117,20 +11117,6 @@ template auto dotc(ExecutionPolicy&& exec, InVec1 v1, InVec2 v2); - // \ref{linalg.algs.blas1.ssq}, scaled sum of squares of a vector's elements - template - struct sum_of_squares_result { - Scalar scaling_factor; - Scalar scaled_sum_of_squares; - }; - template<@\exposconcept{in-vector}@ InVec, class Scalar> - sum_of_squares_result - vector_sum_of_squares(InVec v, sum_of_squares_result init); - template - sum_of_squares_result - vector_sum_of_squares(ExecutionPolicy&& exec, - InVec v, sum_of_squares_result init); - // \ref{linalg.algs.blas1.nrm2}, Euclidean norm of a vector template<@\exposconcept{in-vector}@ InVec, class Scalar> Scalar vector_two_norm(InVec v, Scalar init); @@ -13739,55 +13725,6 @@ \end{itemize} \end{itemdescr} -\rSec3[linalg.algs.blas1.ssq]{Scaled sum of squares of a vector's elements} - -\indexlibraryglobal{vector_sum_of_squares}% -\begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec, class Scalar> - sum_of_squares_result vector_sum_of_squares(InVec v, sum_of_squares_result init); -template - sum_of_squares_result vector_sum_of_squares(ExecutionPolicy&& exec, - InVec v, sum_of_squares_result init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\begin{note} -These functions correspond to the LAPACK function \tcode{xLASSQ}\supercite{lapack}. -\end{note} - -\pnum -\mandates -\tcode{decltype(\exposid{abs-if-needed}(declval()))} is convertible to \tcode{Scalar}. - -\pnum -\effects -Returns a value \tcode{result} such that -\begin{itemize} -\item -\tcode{result.scaling_factor} is the maximum of \tcode{init.scaling_factor} and -\tcode{\exposid{abs-if-needed}(x[i])} -for all \tcode{i} in the domain of \tcode{v}; and -\item -let \tcode{s2init} be -\begin{codeblock} -init.scaling_factor * init.scaling_factor * init.scaled_sum_of_squares -\end{codeblock} -then \tcode{result.scaling_factor * result.scaling_factor * result.scaled_sum_of_squares} -equals the sum of \tcode{s2init} and -the squares of \tcode{\exposid{abs-if-needed}(x[i])} -for all \tcode{i} in the domain of \tcode{v}. -\end{itemize} - -\pnum -\remarks -If \tcode{InVec::value_type}, and \tcode{Scalar} -are all floating-point types or specializations of \tcode{complex}, -and if \tcode{Scalar} has higher precision -than \tcode{InVec::value_type}, -then intermediate terms in the sum use \tcode{Scalar}'s precision or greater. -\end{itemdescr} - \rSec3[linalg.algs.blas1.nrm2]{Euclidean norm of a vector} \indexlibraryglobal{vector_two_norm}% @@ -13825,11 +13762,6 @@ If \tcode{Scalar} has higher precision than \tcode{InVec::value_type}, then intermediate terms in the sum use \tcode{Scalar}'s precision or greater. -\begin{note} -An implementation of this function for floating-point types \tcode{T} -can use the \tcode{scaled_sum_of_squares} result from -\tcode{vector_sum_of_squares(x, \{.scaling_factor=1.0, .scaled_sum_of_squares=init\})}. -\end{note} \end{itemdescr} \indexlibraryglobal{vector_two_norm}% From ee7533acf6f26669edd3601df3a7b4d807b3204f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 20:58:59 -0800 Subject: [PATCH 11/54] LWG4304 std::optional is ill-formed due to value_or --- source/utilities.tex | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/utilities.tex b/source/utilities.tex index 9c6390be1b..c8e3d90a26 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -4887,6 +4887,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{T} is a non-array object type. + \pnum Let \tcode{X} be \tcode{remove_cv_t}. @@ -4900,6 +4904,14 @@ \begin{codeblock} return has_value() ? *@\exposid{val}@ : static_cast(std::forward(u)); \end{codeblock} + +\pnum +\remarks +The return type is unspecified if +\tcode{T} is an array type or a non-object type. +\begin{note} +This is to avoid the declaration being ill-formed. +\end{note} \end{itemdescr} \rSec3[optional.ref.monadic]{Monadic operations} From 1264bd8aaed1105fa2d911bcda29c7f3ec87350a Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 21:38:21 -0800 Subject: [PATCH 12/54] LWG4308 std::optional::iterator can't be a contiguous iterator for some T --- source/utilities.tex | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/source/utilities.tex b/source/utilities.tex index c8e3d90a26..f6c1c47b0e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -4470,8 +4470,9 @@ template class optional { public: - using value_type = T; - using iterator = @\impdefnc@; // see~\ref{optional.ref.iterators} + using value_type = T; + using iterator = @\impdefnc@; // present only if \tcode{T} is an object type other than an array + // of unknown bound; see~\ref{optional.ref.iterators} public: // \ref{optional.ref.ctor}, constructors @@ -4504,8 +4505,8 @@ constexpr void swap(optional& rhs) noexcept; // \ref{optional.ref.iterators}, iterator support - constexpr iterator begin() const noexcept; - constexpr iterator end() const noexcept; + constexpr auto begin() const noexcept; + constexpr auto end() const noexcept; // \ref{optional.ref.observe}, observers constexpr T* operator->() const noexcept; @@ -4779,7 +4780,8 @@ \rSec3[optional.ref.iterators]{Iterator support} \begin{itemdecl} -using iterator = @\impdef@; +using iterator = @\impdefnc@; // present only if \tcode{T} is an object type other than an array + // of unknown bound \end{itemdecl} \begin{itemdescr} @@ -4797,22 +4799,31 @@ \end{itemdescr} \begin{itemdecl} -constexpr iterator begin() const noexcept; +constexpr auto begin() const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{T} is an object type other than an array of unknown bound. + \pnum \returns - If \tcode{has_value()} is \tcode{true}, - an iterator referring to \tcode{*\exposid{val}}. - Otherwise, a past-the-end iterator value. + An object \tcode{i} of type \tcode{iterator}, such that + \tcode{i} is an iterator referring to \tcode{*\exposid{val}} + if \tcode{has_value()} is \tcode{true}, and + a past-the-end iterator value otherwise. \end{itemdescr} \begin{itemdecl} -constexpr iterator end() const noexcept; +constexpr auto end() const noexcept; \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{T} is an object type other than an array of unknown bound. + \pnum \returns \tcode{begin() + has_value()}. From 2e42017ebd25c182ddfe2e78e27c9f592cad23e6 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 22:06:10 -0800 Subject: [PATCH 13/54] LWG4316 {can_}substitute specification is ill-formed Fixes NB US 114-175 (C++26 CD). --- source/meta.tex | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 577d4d0919..856541aabd 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -6185,6 +6185,19 @@ \rSec2[meta.reflection.substitute]{Reflection substitution} +\pnum +Let \tcode{\placeholder{TARG-SPLICE}(x)} be: +\begin{itemize} +\item +\tcode{template [: x :]} if \tcode{is_template(x)} is \tcode{true}, otherwise + +\item +\tcode{typename [: x :]} if \tcode{is_type(x)} is \tcode{true}, otherwise + +\item +\tcode{([: x :])}. +\end{itemize} + \begin{itemdecl} template concept @\deflibconcept{reflection_range}@ = @@ -6205,7 +6218,7 @@ \pnum \returns -\tcode{true} if \tcode{Z<[:Args:]...>} is a valid \grammarterm{template-id}\iref{temp.names} +\tcode{true} if \tcode{Z<\placeholder{TARG-SPLICE}(Args)...>} is a valid \grammarterm{template-id}\iref{temp.names} that does not name a function whose type contains an undeduced placeholder type. Otherwise, \tcode{false}. @@ -6219,7 +6232,7 @@ \pnum \begin{note} -If forming \tcode{Z<[:Args:]...>} leads to a failure +If forming \tcode{Z<\placeholder{TARG-SPLICE}(Args)...>} leads to a failure outside of the immediate context, the program is ill-formed. \end{note} @@ -6240,7 +6253,7 @@ \pnum \returns -\tcode{\reflexpr{Z<[:Args:]...>}}. +\tcode{\reflexpr{Z<\placeholder{TARG-SPLICE}(Args)...>}}. \pnum \throws @@ -6249,7 +6262,7 @@ \pnum \begin{note} -If forming \tcode{Z<[:Args:]...>} leads to a failure outside of the immediate context, +If forming \tcode{Z<\placeholder{TARG-SPLICE}(Args)...>} leads to a failure outside of the immediate context, the program is ill-formed. \end{note} From c47de72262cb942413eb9d621c545b1de51f6f74 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 22:14:33 -0800 Subject: [PATCH 14/54] LWG4358 [exec.as.awaitable] is using "Preconditions:" when it should probably be described in the constraint --- source/exec.tex | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index acf0ebfef5..1691c368a7 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -6754,16 +6754,8 @@ where \tcode{A} is the type of the expression above. \item Otherwise, \tcode{(void(p), expr)} -if \tcode{\exposconcept{is-awaitable}} is \tcode{true}, -where \tcode{U} is an unspecified class type -that is not \tcode{Promise} and -that lacks a member named \tcode{await_transform}. - -\expects -\tcode{\exposconcept{is-awaitable}} is \tcode{true} and -the expression \tcode{co_await expr} -in a coroutine with promise type \tcode{U} is expression-equivalent to -the same expression in a coroutine with promise type \tcode{Promise}. +if \tcode{decltype(\exposid{GET-AWAITER}(expr))} +satisfies \tcode{\exposconcept{is-awaiter}}. \item Otherwise, \tcode{\exposid{sender-awaitable}\{\exposid{adapted-expr}, p\}} if From d9563f3b1d07904c551a1c5114f293abbb857127 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 22:29:26 -0800 Subject: [PATCH 15/54] LWG4360 awaitable-sender concept should qualify use of awaitable-receiver type --- source/exec.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 1691c368a7..58b82316ba 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -6612,7 +6612,8 @@ template concept @\defexposconcept{awaitable-sender}@ = @\exposconcept{single-sender}@> && - @\libconcept{sender_to}@ && // \seebelow + @\libconcept{sender_to}@::@\exposid{awaitable-receiver}@> && // \seebelow requires (Promise& p) { { p.unhandled_stopped() } -> @\libconcept{convertible_to}@>; }; From 96cc88abad513e28a657d1051f392abf625c3a0f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 22:35:57 -0800 Subject: [PATCH 16/54] LWG4369 check-types function for upon_error and upon_stopped is wrong Fixes NB US 219-350 (C++26 CD). --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 58b82316ba..436deedab3 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -3812,7 +3812,7 @@ Equivalent to: \begin{codeblock} auto cs = get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(); -auto fn = [](set_value_t(*)(Ts...)) { +auto fn = [](@\exposid{decayed-typeof}@<@\exposid{set-cpo}@>(*)(Ts...)) { if constexpr (!@\libconcept{invocable}@>, Ts...>) throw @\placeholder{unspecified-exception}@(); }; From 7c2eeb6259d108949bd5478e57655ac97e7ad067 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 22:50:50 -0800 Subject: [PATCH 17/54] LWG4376 ABI tag in return type of [simd.mask.unary] is overconstrained Fixes NB DE 298, DE 297 (C++26 CD). Also fixes LWG4238. --- source/numerics.tex | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 5a185aefe4..1e49880eeb 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -19958,9 +19958,9 @@ // \ref{simd.mask.unary}, \tcode{basic_mask} unary operators constexpr basic_mask operator!() const noexcept; - constexpr basic_vec<@\exposid{integer-from}@, Abi> operator+() const noexcept; - constexpr basic_vec<@\exposid{integer-from}@, Abi> operator-() const noexcept; - constexpr basic_vec<@\exposid{integer-from}@, Abi> operator~() const noexcept; + constexpr @\seebelow@ operator+() const noexcept; + constexpr @\seebelow@ operator-() const noexcept; + constexpr @\seebelow@ operator~() const noexcept; // \ref{simd.mask.conv}, \tcode{basic_mask} conversions template @@ -20174,9 +20174,9 @@ \indexlibrarymember{operator~}{basic_mask} \begin{itemdecl} constexpr basic_mask operator!() const noexcept; -constexpr basic_vec<@\exposid{integer-from}@, Abi> operator+() const noexcept; -constexpr basic_vec<@\exposid{integer-from}@, Abi> operator-() const noexcept; -constexpr basic_vec<@\exposid{integer-from}@, Abi> operator~() const noexcept; +constexpr @\seebelow@ operator+() const noexcept; +constexpr @\seebelow@ operator-() const noexcept; +constexpr @\seebelow@ operator~() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -20188,6 +20188,17 @@ A data-parallel object where the $i^\text{th}$ element is initialized to the results of applying \placeholder{op} to \tcode{operator[]($i$)} for all $i$ in the range of \range{0}{size()}. + +\pnum +\remarks +If there exists a vectorizable signed integer type \tcode{I} such that +\tcode{sizeof(I) == Bytes} is \tcode{true}, +\tcode{operator+}, \tcode{operator-}, and \tcode{operator~} +return an enabled specialization \tcode{R} of \tcode{basic_vec} such that +\tcode{R::value_type} denotes \tcode{\exposid{integer-from}} and +\tcode{R::size() == size()} is \tcode{true}. +Otherwise, +these operators are defined as deleted and their return types are unspecified. \end{itemdescr} \rSec3[simd.mask.conv]{Conversions} From bdcfe2c9a54ca350e9bfc59227bb0285a59c635d Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 2 Dec 2025 23:14:53 -0800 Subject: [PATCH 18/54] LWG4383 constant_wrapper's pseudo-mutators are underconstrained --- source/meta.tex | 66 +++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 41 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 856541aabd..db5958e943 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -769,62 +769,47 @@ // pseudo-mutators template<@\exposconcept{constexpr-param}@ T> constexpr auto operator++(this T) noexcept - requires requires(T::value_type x) { ++x; } - { return constant_wrapper<[] { auto c = T::value; return ++c; }()>{}; } + -> constant_wrapper<++Y> { return {}; } template<@\exposconcept{constexpr-param}@ T> constexpr auto operator++(this T, int) noexcept - requires requires(T::value_type x) { x++; } - { return constant_wrapper<[] { auto c = T::value; return c++; }()>{}; } - + -> constant_wrapper { return {}; } template<@\exposconcept{constexpr-param}@ T> constexpr auto operator--(this T) noexcept - requires requires(T::value_type x) { --x; } - { return constant_wrapper<[] { auto c = T::value; return --c; }()>{}; } + -> constant_wrapper<--Y> { return {}; } template<@\exposconcept{constexpr-param}@ T> constexpr auto operator--(this T, int) noexcept - requires requires(T::value_type x) { x--; } - { return constant_wrapper<[] { auto c = T::value; return c--; }()>{}; } + -> constant_wrapper { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator+=(this T, R) noexcept - requires requires(T::value_type x) { x += R::value; } - { return constant_wrapper<[] { auto v = T::value; return v += R::value; }()>{}; } + constexpr auto operator+=(T, R) noexcept + -> constant_wrapper<(T::value += R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator-=(this T, R) noexcept - requires requires(T::value_type x) { x -= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v -= R::value; }()>{}; } + constexpr auto operator-=(T, R) noexcept + -> constant_wrapper<(T::value -= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator*=(this T, R) noexcept - requires requires(T::value_type x) { x *= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v *= R::value; }()>{}; } + constexpr auto operator*=(T, R) noexcept + -> constant_wrapper<(T::value *= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator/=(this T, R) noexcept - requires requires(T::value_type x) { x /= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v /= R::value; }()>{}; } + constexpr auto operator/=(T, R) noexcept + -> constant_wrapper<(T::value /= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator%=(this T, R) noexcept - requires requires(T::value_type x) { x %= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v %= R::value; }()>{}; } + constexpr auto operator%=(T, R) noexcept + -> constant_wrapper<(T::value %= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator&=(this T, R) noexcept - requires requires(T::value_type x) { x &= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v &= R::value; }()>{}; } + constexpr auto operator&=(T, R) noexcept + -> constant_wrapper<(T::value &= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator|=(this T, R) noexcept - requires requires(T::value_type x) { x |= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v |= R::value; }()>{}; } + constexpr auto operator|=(T, R) noexcept + -> constant_wrapper<(T::value |= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator^=(this T, R) noexcept - requires requires(T::value_type x) { x ^= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v ^= R::value; }()>{}; } + constexpr auto operator^=(T, R) noexcept + -> constant_wrapper<(T::value ^= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator<<=(this T, R) noexcept - requires requires(T::value_type x) { x <<= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v <<= R::value; }()>{}; } + constexpr auto operator<<=(T, R) noexcept + -> constant_wrapper<(T::value <<= R::value)> { return {}; } template<@\exposconcept{constexpr-param}@ T, @\exposconcept{constexpr-param}@ R> - constexpr auto operator>>=(this T, R) noexcept - requires requires(T::value_type x) { x >>= R::value; } - { return constant_wrapper<[] { auto v = T::value; return v >>= R::value; }()>{}; } + constexpr auto operator>>=(T, R) noexcept + -> constant_wrapper<(T::value >>= R::value)> { return {}; } }; template<@\exposid{cw-fixed-value}@ X, class> @@ -835,8 +820,7 @@ template<@\exposconcept{constexpr-param}@ R> constexpr auto operator=(R) const noexcept - requires requires(value_type x) { x = R::value; } - { return constant_wrapper<[] { auto v = value; return v = R::value; }()>{}; } + -> constant_wrapper { return {}; } constexpr operator decltype(auto)() const noexcept { return value; } }; From 5941f69f045928583f737a72469de283e265e96c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 00:17:30 -0800 Subject: [PATCH 19/54] LWG4388 Align new definition of va_start with C23 --- source/support.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/support.tex b/source/support.tex index 425e60dab5..746f2a765c 100644 --- a/source/support.tex +++ b/source/support.tex @@ -6416,6 +6416,11 @@ In lieu of the default argument promotions specified in \IsoC{} 6.5.3.3, the definition in~\ref{expr.call} applies. \item +If more than one argument is present for \tcode{va_start} and +any of the second or subsequent arguments +expands to include unbalanced parentheses, or +a preprocessing token that does not convert to a token, +the program is ill-formed, no diagnostic required. The preprocessing tokens comprising the second and subsequent arguments to \tcode{va_start} (if any) are discarded. From 28ab0553eaf9d873a98e280cc4e45de30168fbfe Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 00:30:45 -0800 Subject: [PATCH 20/54] LWG4396 Improve inplace_vector(from_range_t, R&& rg) --- source/containers.tex | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/containers.tex b/source/containers.tex index 57d7cc1a5b..b444afdc0e 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -1810,6 +1810,9 @@ \mandates \tcode{\libconcept{assignable_from}>} is modeled. +For \tcode{inplace_vector}, +if \tcode{ranges::size(rg)} is a constant expression, +then $\tcode{ranges::size(rg)} \le \tcode{a.max_size()}$. \pnum \expects @@ -10991,6 +10994,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +If \tcode{ranges::size(rg)} is a constant expression, +then $\tcode{ranges::size(rg)} \le \tcode{N}$. + \pnum \effects Constructs an \tcode{inplace_vector} with From 88873f06763a8bf24c8d2a8305b4cb512080da6f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 03:04:34 -0800 Subject: [PATCH 21/54] LWG4420 [simd] conversions (constructor, load, stores, gather, and scatter) are incorrectly constrained for types Fixes NB DE 288, DE 285 (C++26 CD). --- source/numerics.tex | 130 +++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 51 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index 1e49880eeb..6b5fbde04c 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -16147,6 +16147,12 @@ bool_constant::value && bool_constant(T()) == T::value>::value; +template + concept @\defexposconceptnc{explicitly-convertible-to}@ = // \expos + requires { + static_cast(declval()); + }; + template using @\exposidnc{deduced-vec-t} = \seebelownc@; // \expos template using @\exposidnc{make-compatible-simd-t} = \seebelownc@; // \expos @@ -16505,56 +16511,52 @@ flags f = {}); template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void unchecked_store(const basic_vec& v, R&& r, flags f = {}); template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void unchecked_store(const basic_vec& v, R&& r, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, iter_difference_t n, flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, iter_difference_t n, const typename basic_vec::mask_type& mask, flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, S last, flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, S last, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void partial_store(const basic_vec& v, R&& r, flags f = {}); template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void partial_store(const basic_vec& v, R&& r, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void partial_store( const basic_vec& v, I first, iter_difference_t n, flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void partial_store( const basic_vec& v, I first, iter_difference_t n, const typename basic_vec::mask_type& mask, flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void partial_store(const basic_vec& v, I first, S last, flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void partial_store(const basic_vec& v, I first, S last, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); // \ref{simd.permute.static}, static permute inline constexpr @\exposid{simd-size-type}@ @\libmember{zero_element}{simd}@ = @\impdefx{value of \tcode{simd::zero_element}}@; @@ -17626,7 +17628,7 @@ \pnum \constraints -\tcode{value_type} satisfies \tcode{\libconcept{constructible_from}}. +\tcode{U} satisfies \tcode{\exposconcept{explicitly-convertible-to}}. \pnum \effects @@ -17660,7 +17662,10 @@ \begin{itemdescr} \pnum \constraints -\tcode{\exposid{simd-size-v} == size()} is \tcode{true}. +\begin{itemize} +\item \tcode{\exposid{simd-size-v} == size()} is \tcode{true}, and +\item \tcode{U} satisfies \tcode{\exposconcept{explicitly-convertible-to}}. +\end{itemize} \pnum \effects @@ -17732,20 +17737,17 @@ \begin{itemize} \item \tcode{R} models \tcode{ranges::\libconcept{contiguous_range}} and \tcode{ranges::\libconcept{sized_range}}, -\item \tcode{ranges::size(r)} is a constant expression, and -\item \tcode{ranges::size(r)} is equal to \tcode{size()}. +\item \tcode{ranges::size(r)} is a constant expression, +\item \tcode{ranges::size(r)} is equal to \tcode{size()}, and +\item \tcode{ranges::range_value_t} is a vectorizable type and + satisfies \tcode{\exposconcept{explicitly-convertible-to}}. \end{itemize} \pnum \mandates -\begin{itemize} - \item - \tcode{ranges::range_value_t} is a vectorizable type, and - \item - if the template parameter pack \tcode{Flags} does not contain - \tcode{\exposid{convert-flag}}, then the conversion from - \tcode{ranges::range_value_t} to \tcode{value_type} is value-preserving. -\end{itemize} +If the template parameter pack \tcode{Flags} does not contain +\tcode{\exposid{convert-flag}}, then the conversion from +\tcode{ranges::range_value_t} to \tcode{value_type} is value-preserving. \pnum \expects @@ -18460,14 +18462,17 @@ \item \tcode{r} be \tcode{R(first, n)} for the overloads with an \tcode{n} parameter and \tcode{R(first, last)} for the overloads with a \tcode{last} - parameter. + parameter; + \item + \tcode{T} be \tcode{typename V::value_type}. \end{itemize} \pnum \mandates \begin{itemize} \item - \tcode{ranges::range_value_t} is a vectorizable type, + \tcode{ranges::range_value_t} is a vectorizable type and + satisfies \tcode{\exposconcept{explicitly-convertible-to}}, \item \tcode{\libconcept{same_as}, V>} is \tcode{true}, \item @@ -18515,28 +18520,27 @@ \indexlibrarymember{unchecked_store}{simd} \begin{itemdecl} template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void unchecked_store(const basic_vec& v, R&& r, flags f = {}); template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void unchecked_store(const basic_vec& v, R&& r, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, iter_difference_t n, flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, iter_difference_t n, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, S last, flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void unchecked_store(const basic_vec& v, I first, S last, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); \end{itemdecl} \begin{itemdescr} @@ -18581,28 +18585,27 @@ \indexlibrarymember{partial_store}{simd} \begin{itemdecl} template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void partial_store(const basic_vec& v, R&& r, flags f = {}); template - requires ranges::@\libconcept{sized_range}@ && @\libconcept{indirectly_writable}@, T> + requires ranges::@\libconcept{sized_range}@ constexpr void partial_store(const basic_vec& v, R&& r, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void partial_store(const basic_vec& v, I first, iter_difference_t n, flags f = {}); template - requires @\libconcept{indirectly_writable}@ constexpr void partial_store(const basic_vec& v, I first, iter_difference_t n, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void partial_store(const basic_vec& v, I first, S last, flags f = {}); template S, class... Flags> - requires @\libconcept{indirectly_writable}@ constexpr void partial_store(const basic_vec& v, I first, S last, - const typename basic_vec::mask_type& mask, flags f = {}); + const typename basic_vec::mask_type& mask, + flags f = {}); \end{itemdecl} \begin{itemdescr} @@ -18621,6 +18624,17 @@ parameter. \end{itemize} +\pnum +\constraints +\begin{itemize} + \item + \tcode{ranges::iterator_t} models + \tcode{\libconcept{indirectly_writable}>}, and + \item + \tcode{T} satisfies + \tcode{\exposconcept{explicitly-convertible-to}>}. +\end{itemize} + \pnum \mandates \begin{itemize} @@ -18656,7 +18670,7 @@ \effects For all $i$ in the range of \range{0}{basic_vec::size()}, if \tcode{mask[$i$] \&\& $i$ < ranges::\brk{}size(r)} is \tcode{true}, evaluates -\tcode{ranges::data(r)[$i$] = v[$i$]}. +\tcode{ranges::data(r)[$i$] = static_cast>(v[\brk{}$i$])}. \end{itemdescr} \rSec3[simd.permute.static]{Static permute} @@ -18890,6 +18904,11 @@ \tcode{T} be \tcode{typename V::value_type}. \end{itemize} +\pnum +\constraints +\tcode{ranges::range_value_t} is a vectorizable type and satisfies +\tcode{\exposconceptx{explicitly-convert\-ible-to}{explicitly-convertible-to}}. + \pnum \mandates \begin{itemize} @@ -18981,7 +19000,16 @@ \pnum \constraints -\tcode{V::size() == I::size()} is \tcode{true}. +\begin{itemize} +\item +\tcode{V::size() == I::size()} is \tcode{true}, +\item +\tcode{ranges::iterator_t} models +\tcode{\libconcept{indirectly_writable}>}, and +\item +\tcode{typename V::value_type} satisfies +\tcode{\exposconcept{explicitly-convertible-to}>}. +\end{itemize} \pnum \mandates @@ -19013,7 +19041,7 @@ \effects For all $i$ in the range \range{0}{I::size()}, if \tcode{mask[$i$] \&\& (indices[$i$] < ranges::size(out))} is \tcode{true}, evaluates -\tcode{ranges::data(out)[indices[$i$]] = v[$i$]}. +\tcode{ranges::data(out)[indices[$i$]] = static_cast>(v[\brk{}$i$])}. \end{itemdescr} \rSec3[simd.creation]{Creation} From 17958536a4015008a55be3175354b002112a229c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 03:14:59 -0800 Subject: [PATCH 22/54] LWG4424 meta::define_aggregate should require a class type Fixes NB US 125-188 (C++26 CD). --- source/meta.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/meta.tex b/source/meta.tex index db5958e943..4de6168c5f 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -6574,7 +6574,7 @@ \begin{itemdescr} \pnum -Let $C$ be the class represented by \tcode{class_type} +Let $C$ be the type represented by \tcode{class_type} and $r_K$ be the $K^\text{th}$ reflection value in \tcode{mdescrs}. For every $r_K$ in \tcode{mdescrs}, let $(T_K, N_K, A_K, W_K, \mathit{NUA}_K)$ be @@ -6583,6 +6583,8 @@ \pnum \constantwhen \begin{itemize} +\item + \tcode{class_type} represents a cv-unqualified class type; \item $C$ is incomplete from every point in the evaluation context; \begin{note} From 58e3bcd591385cf20781d06150de403c689398db Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 03:20:33 -0800 Subject: [PATCH 23/54] LWG4427 meta::dealias needs to work with things that aren't entities Fixes NB US 99-205 (C++26 CD). --- source/meta.tex | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 4de6168c5f..95a10f8d0c 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -4863,12 +4863,9 @@ \begin{itemdescr} \pnum \returns -A reflection representing the underlying entity of what \tcode{r} represents. - -\pnum -\throws -\tcode{meta::exception} unless -\tcode{r} represents an entity. +If \tcode{r} represents an entity, then +a reflection representing the underlying entity of what \tcode{r} represents. +Otherwise, \tcode{r}. \pnum \begin{example} From 1cf3085ed2b55ddc49d508470adf4c15218120c3 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 03:31:49 -0800 Subject: [PATCH 24/54] LWG4428 Metafunctions should not be defined in terms of constant subexpressions Fixes NB US 102-209 (C++26 CD). --- source/meta.tex | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 95a10f8d0c..39f5a6c2d1 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -5422,13 +5422,14 @@ \pnum \throws -\tcode{meta::exception} unless +\tcode{meta::exception} if \begin{itemize} \item - \tcode{nonstatic_data_members_of(\brk{}r, access_context::\brk{}unchecked())} - is a constant subexpression and + the evaluation of + \tcode{nonstatic_data_members_of(r, access_context::unchecked())} + would exit via an exception or \item - \tcode{r} does not represent a closure type. + \tcode{r} represents a closure type. \end{itemize} \end{itemdescr} @@ -5445,9 +5446,9 @@ \pnum \throws -\tcode{meta::exception} unless +\tcode{meta::exception} if the evaluation of \tcode{bases_of(r, access_context::unchecked())} -is a constant subexpression. +would exit via an exception. \end{itemdescr} \indexlibraryglobal{has_inaccessible_subobjects}% @@ -6007,7 +6008,8 @@ \tcode{meta::exception} unless \begin{itemize} \item - \tcode{annotations_of(item)} is a constant expression and + the evaluation of + \tcode{annotations_of(item)} would not exit via an exception and \item \tcode{dealias(type)} represents a type and \tcode{is_complete_type(type)} is \tcode{true}. From cf8a31962f1e9fa4fd306355b87c99c8d89919cc Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 03:43:54 -0800 Subject: [PATCH 25/54] LWG4429 meta::alignment_of should exclude data member description of bit-field Fixes NB US 109-170 (C++26 CD). --- source/meta.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/meta.tex b/source/meta.tex index 39f5a6c2d1..b643ce3e6f 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -5851,7 +5851,9 @@ variable of non-reference type, non-static data member that is not a bit-field, direct base class relationship, or -data member description. +data member description +$(T, N, A, W, \mathit{NUA})$\iref{class.mem.general} +where $W$ is $\bot$. \item If \tcode{dealias(r)} represents a type, then \tcode{is_complete_type(r)} is \tcode{true}. From 8fd182adc4eec3f7a8677282219f6c7079a3f7b7 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 03:50:00 -0800 Subject: [PATCH 26/54] LWG4430 from_chars should not parse "0b" base prefixes --- source/text.tex | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/text.tex b/source/text.tex index ea9cf3f66a..ce605582da 100644 --- a/source/text.tex +++ b/source/text.tex @@ -289,7 +289,10 @@ in the \tcode{"C"} locale for the given nonzero base, as described for \tcode{strtol}, -except that no \tcode{"0x"} or \tcode{"0X"} prefix shall appear +except that +no \tcode{"0b"} or \tcode{"0B"} prefix shall appear +if the value of \tcode{base} is 2, +no \tcode{"0x"} or \tcode{"0X"} prefix shall appear if the value of \tcode{base} is 16, and except that \tcode{'-'} is the only sign that may appear, From a85a2595ff0f0b8d379fb004d4499b9e5e91b1c5 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 03:55:37 -0800 Subject: [PATCH 27/54] LWG4431 Parallel std::ranges::destroy should allow exceptions --- source/memory.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/memory.tex b/source/memory.tex index 09416c774b..ecfe92729b 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -503,15 +503,15 @@ template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I, @\exposconcept{nothrow-sized-sentinel-for}@ S> requires @\libconcept{destructible}@> - I destroy(Ep&& exec, I first, S last) noexcept; // freestanding-deleted, + I destroy(Ep&& exec, I first, S last); // freestanding-deleted, // see \ref{algorithms.parallel.overloads} template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-sized-random-access-range}@ R> requires @\libconcept{destructible}@> - borrowed_iterator_t destroy(Ep&& exec, R&& r) noexcept; // freestanding-deleted, + borrowed_iterator_t destroy(Ep&& exec, R&& r); // freestanding-deleted, // see \ref{algorithms.parallel.overloads} template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{nothrow-random-access-iterator}@ I> requires @\libconcept{destructible}@> - I destroy_n(Ep&& exec, I first, iter_difference_t n) noexcept; // freestanding-deleted, + I destroy_n(Ep&& exec, I first, iter_difference_t n); // freestanding-deleted, // see \ref{algorithms.parallel.overloads} } From 69c4644d810e927754fc47015fba8568f4d27b49 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 04:18:38 -0800 Subject: [PATCH 28/54] LWG4432 Clarify element initialization for meta::reflect_constant_array Fixes NB US 120-181, US 121-182 (C++26 CD). --- source/meta.tex | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index b643ce3e6f..692612fd6a 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -3375,19 +3375,21 @@ \begin{itemdescr} \pnum -Let \tcode{T} be \tcode{ranges::range_value_t}. +Let \tcode{T} be \tcode{ranges::range_value_t} and +$\tcode{\placeholder{e}}_i$ be \tcode{static_cast(*$\tcode{\placeholder{it}}_i$)}, +where $\tcode{\placeholder{it}}_i$ is an iterator to the $i^\text{th}$ element of \tcode{r}. \pnum \mandates \tcode{T} is a structural type\iref{temp.param}, \tcode{is_constructible_v>} is \tcode{true}, and -\tcode{is_copy_constructible_v} is \tcode{true}. +\tcode{T} satisfies \libconcept{copy_constructible}. \pnum Let $V$ be the pack of values of type \tcode{info} of the same size as \tcode{r}, -where the $i^\text{th}$ element is \tcode{reflect_constant($\tcode{e}_i$)}, -where $\tcode{e}_i$ is the $i^\text{th}$ element of \tcode{r}. +where the $i^\text{th}$ element is +\tcode{reflect_constant($\tcode{\placeholder{e}}_i$)}. \pnum Let $P$ be @@ -3409,9 +3411,10 @@ \pnum \throws -\tcode{meta::exception} unless -\tcode{reflect_constant(e)} is a constant subexpression -for every element \tcode{e} of \tcode{r}. +Any exception thrown by the evaluation of any $\tcode{\placeholder{e}}_i$, or +\tcode{meta::exception} +if evaluation of any \tcode{reflect_constant($\tcode{\placeholder{e}}_i$)} +would exit via an exception. \pnum \begin{note} From 48f8b437b987b17209bf3119ccb55a20173bd5d3 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 15:18:00 -0800 Subject: [PATCH 29/54] LWG4433 Incorrect query for C language linkage Fixes NB US 97-203 (C++26 CD). --- source/meta.tex | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 692612fd6a..ebc75dc9b1 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -4360,13 +4360,11 @@ \indexlibraryglobal{has_internal_linkage}% \indexlibraryglobal{has_module_linkage}% \indexlibraryglobal{has_external_linkage}% -\indexlibraryglobal{has_c_language_linkage}% \indexlibraryglobal{has_linkage}% \begin{itemdecl} consteval bool has_internal_linkage(info r); consteval bool has_module_linkage(info r); consteval bool has_external_linkage(info r); -consteval bool has_c_language_linkage(info r); consteval bool has_linkage(info r); \end{itemdecl} @@ -4382,11 +4380,27 @@ whose name has internal linkage, module linkage, -C language linkage, or +external linkage, or any linkage, respectively\iref{basic.link}. Otherwise, \tcode{false}. \end{itemdescr} +\indexlibraryglobal{has_c_language_linkage}% +\begin{itemdecl} +consteval bool has_c_language_linkage(info r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{r} represents a +variable, +function, or +function type +with C language linkage. +Otherwise, \tcode{false}. +\end{itemdescr} + \indexlibraryglobal{is_complete_type}% \begin{itemdecl} consteval bool is_complete_type(info r); From 3ff98a912a5adf95253ccf92d8273e64ae67ddc1 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 15:19:51 -0800 Subject: [PATCH 30/54] LWG4434 meta::is_accessible does not need to consider incomplete D --- source/meta.tex | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index ebc75dc9b1..fa59029200 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -5395,14 +5395,8 @@ \pnum \throws \tcode{meta::exception} if -\begin{itemize} -\item \tcode{r} represents a class member - for which \tcode{\exposid{PARENT-CLS}(r)} is an incomplete class or -\item - \tcode{r} represents a direct base class relationship $(D, B)$ - for which $D$ is incomplete. -\end{itemize} + for which \tcode{\exposid{PARENT-CLS}(r)} is an incomplete class. \pnum \begin{example} From 383f9813b5895b3165ca3d33a4f3fb77582c5943 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 15:28:50 -0800 Subject: [PATCH 31/54] LWG4435 meta::has_identifier doesn't handle all types --- source/meta.tex | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index fa59029200..7ac6d08344 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -3736,8 +3736,19 @@ Otherwise, if \tcode{r} represents an unnamed entity, then \tcode{false}. \item - Otherwise, if \tcode{r} represents a class type, + Otherwise, if \tcode{r} represents a type alias, then \tcode{!has_template_arguments(r)}. +\item + Otherwise, if \tcode{r} represents a type, + then \tcode{true} if + \begin{itemize} + \item + \tcode{r} represents a cv-unqualified class type and + \tcode{has_template_arguments(r)} is \tcode{false}, or + \item + \tcode{r} represents a cv-unqualified enumeration type. + \end{itemize} + Otherwise, \tcode{false}. \item Otherwise, if \tcode{r} represents a function, then \tcode{true} if \tcode{has_template_arguments(r)} is \tcode{false} @@ -3805,9 +3816,6 @@ then \tcode{false} if the declaration of that structured binding was instantiated from a structured binding pack. Otherwise, \tcode{true}. -\item - Otherwise, if \tcode{r} represents a type alias, - then \tcode{!has_template_arguments(r)}. \item Otherwise, if \tcode{r} represents an enumerator, From eafcd68294add7c2219b043baac0f25ae0508cd0 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 15:53:20 -0800 Subject: [PATCH 32/54] LWG4438 Bad expression in [exec.when.all] Fixes NB US 220-344, US 224-342 (C++26 CD). --- source/exec.tex | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index 436deedab3..f13ced3c22 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -4424,22 +4424,24 @@ \begin{codeblock} template constexpr auto @\exposid{make-when-all-env}@(inplace_stop_source& stop_src, // \expos - Env&& env) noexcept { - return @\seebelow@; -} + Env&& env) noexcept; \end{codeblock} -Returns an object \tcode{e} such that + +\pnum +\returns +An object \tcode{e} such that \begin{itemize} \item \tcode{decltype(e)} models \exposconcept{queryable}, and \item \tcode{e.query(get_stop_token)} is expression-equivalent to -\tcode{state.\exposid{stop-src}.get_token()}, and +\tcode{stop_src.get_token()}, and \item given a query object \tcode{q} -with type other than \cv{} \tcode{get_stop_token_t} and -whose type satisfies \exposconceptx{forwarding-\brk{}query}{forwarding-query}, -\tcode{e.query(q)} is expression-equivalent to \tcode{get_env(rcvr).query(q)}. +with type other than \cv{} \tcode{get_stop_token_t}, +\tcode{e.query(q)} is expression-equivalent to \tcode{env.query(q)} +if the type of \tcode{q} satisfies \exposconcept{forwarding-query}, and +ill-formed otherwise. \end{itemize} \pnum From 6dd3ccad15ea887fd755e50a60edc83fb8b94b54 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 15:56:19 -0800 Subject: [PATCH 33/54] LWG4439 std::optional::swap possibly selects ADL-found swap --- source/utilities.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utilities.tex b/source/utilities.tex index f6c1c47b0e..d7841e3bbb 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -4774,7 +4774,7 @@ \begin{itemdescr} \pnum \effects -Equivalent to: \tcode{swap(\exposid{val}, rhs.\exposid{val})}. +Equivalent to: \tcode{std::swap(\exposid{val}, rhs.\exposid{val})}. \end{itemdescr} \rSec3[optional.ref.iterators]{Iterator support} From 32ba1393474fd8bbbb3e93c05d41fbdf919e5af8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 16:06:33 -0800 Subject: [PATCH 34/54] LWG4440 Forward declarations of entities need also in entries Fixes NB US 65-116 (C++26 CD). --- source/support.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/support.tex b/source/support.tex index 746f2a765c..da55ba530e 100644 --- a/source/support.tex +++ b/source/support.tex @@ -609,7 +609,7 @@ #define @\defnlibxname{cpp_lib_byte}@ 201603L // freestanding, also in \libheader{cstddef} #define @\defnlibxname{cpp_lib_byteswap}@ 202110L // freestanding, also in \libheader{bit} #define @\defnlibxname{cpp_lib_char8_t}@ 201907L - // freestanding, also in \libheader{atomic}, \libheader{filesystem}, \libheader{istream}, \libheader{limits}, \libheader{locale}, \libheader{ostream}, \libheader{string}, + // freestanding, also in \libheader{atomic}, \libheader{filesystem}, \libheader{iosfwd}, \libheader{istream}, \libheader{limits}, \libheader{locale}, \libheader{ostream}, \libheader{string}, // \libheader{string_view} #define @\defnlibxname{cpp_lib_chrono}@ 202306L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_chrono_udls}@ 201304L // also in \libheader{chrono} @@ -836,7 +836,7 @@ #define @\defnlibxname{cpp_lib_source_location}@ 201907L // freestanding, also in \libheader{source_location} #define @\defnlibxname{cpp_lib_span}@ 202311L // freestanding, also in \libheader{span} #define @\defnlibxname{cpp_lib_span_initializer_list}@ 202311L // freestanding, also in \libheader{span} -#define @\defnlibxname{cpp_lib_spanstream}@ 202106L // also in \libheader{spanstream} +#define @\defnlibxname{cpp_lib_spanstream}@ 202106L // also in \libheader{iosfwd}, \libheader{spanstream} #define @\defnlibxname{cpp_lib_ssize}@ 201902L // freestanding, also in \libheader{iterator} #define @\defnlibxname{cpp_lib_sstream_from_string_view}@ 202306L // also in \libheader{sstream} #define @\defnlibxname{cpp_lib_stacktrace}@ 202011L // also in \libheader{stacktrace} @@ -849,7 +849,7 @@ #define @\defnlibxname{cpp_lib_string_udls}@ 201304L // also in \libheader{string} #define @\defnlibxname{cpp_lib_string_view}@ 202403L // also in \libheader{string}, \libheader{string_view} #define @\defnlibxname{cpp_lib_submdspan}@ 202411L // freestanding, also in \libheader{mdspan} -#define @\defnlibxname{cpp_lib_syncbuf}@ 201803L // also in \libheader{syncstream} +#define @\defnlibxname{cpp_lib_syncbuf}@ 201803L // also in \libheader{iosfwd}, \libheader{syncstream} #define @\defnlibxname{cpp_lib_task}@ 202506L // also in \libheader{execution} #define @\defnlibxname{cpp_lib_text_encoding}@ 202306L // also in \libheader{text_encoding} #define @\defnlibxname{cpp_lib_three_way_comparison}@ 201907L // freestanding, also in \libheader{compare} From 5d034f59648b2b583106c1cc273a1006f772699d Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 16:24:20 -0800 Subject: [PATCH 35/54] LWG4441 ranges::rotate do not handle sized-but-not-sized-sentinel ranges correctly Fixes NB US 161-258 (C++26 CD). --- source/algorithms.tex | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 37ab57f256..d24ae33d07 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -8261,7 +8261,8 @@ \effects Equivalent to: \begin{codeblock} -return ranges::rotate(std::forward(exec), ranges::begin(r), middle, ranges::end(r)); +return ranges::rotate(std::forward(exec), ranges::begin(r), middle, + ranges::begin(r) + ranges::distance(r)); \end{codeblock} \end{itemdescr} @@ -8386,8 +8387,10 @@ \effects Equivalent to: \begin{codeblock} -return ranges::rotate_copy(std::forward(exec), ranges::begin(r), middle, ranges::end(r), - ranges::begin(result_r), ranges::end(result_r)); +return ranges::rotate_copy(std::forward(exec), ranges::begin(r), middle, + ranges::begin(r) + ranges::distance(r), + ranges::begin(result_r), + ranges::begin(result_r) + ranges::distance(result_r)); \end{codeblock} \end{itemdescr} @@ -9007,7 +9010,8 @@ Equivalent to: \begin{codeblock} return ranges::partial_sort(std::forward(exec), ranges::begin(r), middle, - ranges::end(r), comp, proj); + ranges::begin(r) + ranges::distance(r), + comp, proj); \end{codeblock} \end{itemdescr} @@ -9391,7 +9395,8 @@ \effects Equivalent to: \begin{codeblock} -return ranges::nth_element(std::forward(exec), ranges::begin(r), nth, ranges::end(r), +return ranges::nth_element(std::forward(exec), ranges::begin(r), nth, + ranges::begin(r) + ranges::distance(r), comp, proj); \end{codeblock} \end{itemdescr} @@ -10264,7 +10269,8 @@ Equivalent to: \begin{codeblock} return ranges::inplace_merge(std::forward(exec), ranges::begin(r), middle, - ranges::end(r), comp, proj); + ranges::begin(r) + ranges::distance(r), + comp, proj); \end{codeblock} \end{itemdescr} From 06aa28edbf21be55a4a03c0344106460ce38ad52 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 16:43:08 -0800 Subject: [PATCH 36/54] LWG4442 Clarify expr and fn for meta::reflect_object and meta::reflect_function Fixes NB US 118-179 (C++26 CD). --- source/meta.tex | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 7ac6d08344..1add6a3a2b 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -6388,9 +6388,11 @@ \pnum \throws -\tcode{meta::exception} unless -\tcode{expr} is suitable for use as a constant template argument -for a constant template parameter of type \tcode{T\&}\iref{temp.arg.nontype}. +\tcode{meta::exception} if +\tcode{E} is not suitable for use as a constant template argument +for a constant template parameter of type \tcode{T\&}\iref{temp.arg.nontype}, +where \tcode{E} is an lvalue constant expression that +computes the object that \tcode{expr} refers to. \end{itemdescr} \indexlibraryglobal{reflect_function}% @@ -6410,9 +6412,11 @@ \pnum \throws -\tcode{meta::exception} unless -\tcode{fn} is suitable for use as a constant template argument -for a constant template parameter of type \tcode{T\&}\iref{temp.arg.nontype}. +\tcode{meta::exception} if +\tcode{F} is not suitable for use as a constant template argument +for a constant template parameter of type \tcode{T\&}\iref{temp.arg.nontype}, +where \tcode{F} is an lvalue constant expression that +computes the function that \tcode{fn} refers to. \end{itemdescr} \rSec2[meta.reflection.define.aggregate]{Reflection class definition generation} From 7e4df5a90a4f8dfb97557864521084318f2da52e Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 17:10:52 -0800 Subject: [PATCH 37/54] LWG4443 Clean up identifier comparisons in meta::define_aggregate Fixes NB US 127-190 (C++26 CD). --- source/meta.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index 1add6a3a2b..ab5376abbe 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -6627,9 +6627,9 @@ then either: \begin{itemize} \item - \tcode{$N_K$ != $N_L$} is \tcode{true} or + $N_K$ is not the same identifier as $N_L$ or \item - \tcode{$N_K$ == u8"_"} is \tcode{true}. + $N_K$ is the identifier \tcode{_} (\ucode{005f} low line). \begin{note} Every provided identifier is unique or \tcode{"_"}. \end{note} @@ -6665,7 +6665,7 @@ If $N_K$ is $\bot$, $M_K$ is an unnamed bit-field. Otherwise, $M_K$ is a non-static data member whose name is the identifier - determined by the character sequence encoded by $N_K$ in UTF-8. + $N_K$. \item The type of $M_K$ is $T_K$. \item From 81fe012dfb4f97ba80ff9f3897cd18c6e60f8263 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 19:38:15 -0800 Subject: [PATCH 38/54] LWG4444 Fix default template arguments for ranges::replace and ranges::replace_if Fixes NB US 159-259 (C++26 CD). --- source/algorithms.tex | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index d24ae33d07..7d80a8ced6 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -2097,13 +2097,13 @@ namespace ranges { template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T1 = projected_value_t, class T2 = T1> + class T1 = projected_value_t, class T2 = iter_value_t> requires @\libconcept{indirectly_writable}@ && @\libconcept{indirect_binary_predicate}@, const T1*> constexpr I replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); template<@\libconcept{input_range}@ R, class Proj = identity, - class T1 = projected_value_t, Proj>, class T2 = T1> + class T1 = projected_value_t, Proj>, class T2 = range_value_t> requires @\libconcept{indirectly_writable}@, const T2&> && @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> @@ -2111,13 +2111,14 @@ replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, - class Proj = identity, class T1 = projected_value_t, class T2 = T1> + class Proj = identity, + class T1 = projected_value_t, class T2 = iter_value_t> requires @\libconcept{indirectly_writable}@ && @\libconcept{indirect_binary_predicate}@, const T1*> I replace(Ep&& exec, I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); // freestanding-deleted template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, - class T1 = projected_value_t, Proj>, class T2 = T1> + class T1 = projected_value_t, Proj>, class T2 = range_value_t> requires @\libconcept{indirectly_writable}@, const T2&> && @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> @@ -2126,24 +2127,24 @@ Proj proj = {}); // freestanding-deleted template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T = projected_value_t, + class T = iter_value_t, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_writable}@ constexpr I replace_if(I first, S last, Pred pred, const T& new_value, Proj proj = {}); - template<@\libconcept{input_range}@ R, class Proj = identity, class T = projected_value_t, + template<@\libconcept{input_range}@ R, class Proj = identity, class T = range_value_t, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{indirectly_writable}@, const T&> constexpr borrowed_iterator_t replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, - class Proj = identity, class T = projected_value_t, + class Proj = identity, class T = iter_value_t, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_writable}@ I replace_if(Ep&& exec, I first, S last, Pred pred, const T& new_value, Proj proj = {}); // freestanding-deleted template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, - class T = projected_value_t, Proj>, + class T = range_value_t, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{indirectly_writable}@, const T&> borrowed_iterator_t @@ -7152,26 +7153,26 @@ Predicate pred, const T& new_value); template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T1 = projected_value_t, class T2 = T1> + class T1 = projected_value_t, class T2 = iter_value_t> requires @\libconcept{indirectly_writable}@ && @\libconcept{indirect_binary_predicate}@, const T1*> constexpr I ranges::replace(I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); template<@\libconcept{input_range}@ R, class Proj = identity, - class T1 = projected_value_t, Proj>, class T2 = T1> + class T1 = projected_value_t, Proj>, class T2 = range_value_t> requires @\libconcept{indirectly_writable}@, const T2&> && @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> constexpr borrowed_iterator_t ranges::replace(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}); template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, - class Proj = identity, class T1 = projected_value_t, class T2 = T1> + class Proj = identity, class T1 = projected_value_t, class T2 = iter_value_t> requires @\libconcept{indirectly_writable}@ && @\libconcept{indirect_binary_predicate}@, const T1*> I ranges::replace(Ep&& exec, I first, S last, const T1& old_value, const T2& new_value, Proj proj = {}); template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, - class T1 = projected_value_t, Proj>, class T2 = T1> + class T1 = projected_value_t, Proj>, class T2 = range_value_t> requires @\libconcept{indirectly_writable}@, const T2&> && @\libconcept{indirect_binary_predicate}@, Proj>, const T1*> @@ -7180,24 +7181,24 @@ Proj proj = {}); template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, - class T = projected_value_t, + class T = iter_value_t, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_writable}@ constexpr I ranges::replace_if(I first, S last, Pred pred, const T& new_value, Proj proj = {}); -template<@\libconcept{input_range}@ R, class Proj = identity, class T = projected_value_t, Proj>, +template<@\libconcept{input_range}@ R, class Proj = identity, class T = range_value_t, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{indirectly_writable}@, const T&> constexpr borrowed_iterator_t ranges::replace_if(R&& r, Pred pred, const T& new_value, Proj proj = {}); template<@\exposconcept{execution-policy}@ Ep, @\libconcept{random_access_iterator}@ I, @\libconcept{sized_sentinel_for}@ S, - class Proj = identity, class T = projected_value_t, + class Proj = identity, class T = iter_value_t, @\libconcept{indirect_unary_predicate}@> Pred> requires @\libconcept{indirectly_writable}@ I ranges::replace_if(Ep&& exec, I first, S last, Pred pred, const T& new_value, Proj proj = {}); template<@\exposconcept{execution-policy}@ Ep, @\exposconcept{sized-random-access-range}@ R, class Proj = identity, - class T = projected_value_t, Proj>, + class T = range_value_t, @\libconcept{indirect_unary_predicate}@, Proj>> Pred> requires @\libconcept{indirectly_writable}@, const T&> borrowed_iterator_t From 816b12aaa1a5965fa9f63276a754ed3189a517e7 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 19:39:32 -0800 Subject: [PATCH 39/54] LWG4445 sch_ must not be in moved-from state Fixes NB US 239-367 (C++26 CD). --- source/exec.tex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/exec.tex b/source/exec.tex index f13ced3c22..62d5e3ef95 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -7001,6 +7001,9 @@ && @\libconcept{scheduler}@ explicit task_scheduler(Sch&& sch, Allocator alloc = {}); + task_scheduler(const task_scheduler&) = default; + task_scheduler& operator=(const task_scheduler&) = default; + @\exposid{ts-sender}@ schedule(); friend bool operator==(const task_scheduler& lhs, const task_scheduler& rhs) From 4318098f57017523df8471e58d410c87006c9d34 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 19:41:15 -0800 Subject: [PATCH 40/54] LWG4446 Bad phrasing for SCHED(s) Fixes NB US 240-370 (C++26 CD). --- source/exec.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 62d5e3ef95..b491155d5e 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -7023,7 +7023,8 @@ \tcode{task_scheduler} is a class that models \libconcept{scheduler}\iref{exec.sched}. Given an object \tcode{s} of type \tcode{task_scheduler}, let -\tcode{\exposid{SCHED}(s)} be the object owned by \tcode{s.\exposid{sch_}}. +\tcode{\exposid{SCHED}(s)} be the object +pointed to by the pointer owned by \tcode{s.\exposid{sch_}}. \indexlibraryctor{task_scheduler} \begin{itemdecl} From 05fc3e54c05dff92e81c5c6b58e8acc688cdcbed Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 20:15:18 -0800 Subject: [PATCH 41/54] =?UTF-8?q?LWG4447=20Remove=20unnecessary=20sizeof?= =?UTF-8?q?=E2=80=A6(Env)=20>=201=20condition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes NB US 206-325 (C++26 CD). --- source/exec.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/exec.tex b/source/exec.tex index b491155d5e..98f488aba3 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -791,8 +791,7 @@ For type \tcode{Sndr} and pack of types \tcode{Env}, let \tcode{CS} be \tcode{completion_signatures_of_t}. Then \tcode{\exposid{single-sender-value-type}} is ill-formed -if \tcode{CS} is ill-formed or -if \tcode{sizeof...(Env) > 1} is \tcode{true}; +if \tcode{CS} is ill-formed; otherwise, it is an alias for: \begin{itemize} \item From 5d4d8ffa774d1613315147260c2d77582996d9a0 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 20:17:13 -0800 Subject: [PATCH 42/54] LWG4448 Do not forward fn in completion_signatures Fixes NB US 230-360 (C++26 CD). --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 98f488aba3..48c397ffd0 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -6129,7 +6129,7 @@ template static constexpr void @\exposid{for-each}@(Fn&& fn) { // \expos - (std::forward(fn)(static_cast(nullptr)), ...); + (fn(static_cast(nullptr)), ...); } }; From 373ad3757e5d8e018b0fc0e82ea3aa578a429411 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 20:20:43 -0800 Subject: [PATCH 43/54] LWG4449 define_aggregate members must be public --- source/meta.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/meta.tex b/source/meta.tex index ab5376abbe..565eca7d7a 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -6658,6 +6658,7 @@ \item For each $r_K$, there is a corresponding entity $M_K$ + with public access belonging to the class scope of $D$ with the following properties: \begin{itemize} From b61d476a563f2c08d0636e1d5d961a23dab335db Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 20:41:33 -0800 Subject: [PATCH 44/54] LWG4450 std::atomic_ref::store_key should be disabled for const T Fixes NB US 193-311 (C++26 CD). --- source/threads.tex | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/threads.tex b/source/threads.tex index 089a0ea4f7..cb06f6bba7 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -3774,6 +3774,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{integral-type}>} is \tcode{false}. + \pnum \expects \tcode{order} is \tcode{memory_order::relaxed}, @@ -4028,6 +4032,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{floating-point-type}>} is \tcode{false}. + \pnum \expects \tcode{order} is \tcode{memory_order::relaxed}, @@ -4263,6 +4271,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_const_v<\placeholder{pointer-type}>} is \tcode{false}. + \pnum \mandates \tcode{remove_pointer_t<\placeholder{pointer-type}>} is a complete object type. From 7102286f02f946e5d1d046bafd70af3c24364390 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 20:56:26 -0800 Subject: [PATCH 45/54] LWG4451 make_shared should not refer to a type U[N] for runtime N Fixes NB US 76-139 (C++26 CD). --- source/memory.tex | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/memory.tex b/source/memory.tex index ecfe92729b..efbf7fee28 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -4290,13 +4290,13 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[]}. +\tcode{T} is an array of unknown bound. \pnum \returns -A \tcode{shared_ptr} to an object of type \tcode{U[N]} -with a default initial value, -where \tcode{U} is \tcode{remove_extent_t}. +A \tcode{shared_ptr} to an array of +\tcode{N} elements of type \tcode{remove_extent_t} +with a default initial value. \pnum \begin{example} @@ -4321,7 +4321,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[N]}. +\tcode{T} is an array of known bound. \pnum \returns @@ -4353,13 +4353,13 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[]}. +\tcode{T} is an array of unknown bound. \pnum \returns -A \tcode{shared_ptr} to an object of type \tcode{U[N]}, -where \tcode{U} is \tcode{remove_extent_t} and -each array element has an initial value of \tcode{u}. +A \tcode{shared_ptr} to an array of +\tcode{N} elements of type \tcode{remove_extent_t} +where each array element has an initial value of \tcode{u}. \pnum \begin{example} @@ -4387,7 +4387,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is of the form \tcode{U[N]}. +\tcode{T} is an array of known bound. \pnum \returns @@ -4455,8 +4455,8 @@ \pnum \returns -A \tcode{shared_ptr} to an object of type \tcode{U[N]}, -where \tcode{U} is \tcode{remove_extent_t}. +A \tcode{shared_ptr} to an array of +\tcode{N} elements of type \tcode{remove_extent_t}. \pnum \begin{example} From daffc091ddec458fc2f7caa281bbe7e9bad00d39 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:01:51 -0800 Subject: [PATCH 46/54] LWG4452 Make deref-move constexpr --- source/algorithms.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 7d80a8ced6..513939cf50 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -13548,7 +13548,7 @@ } template - decltype(auto) @\exposid{deref-move}@(I& it) { + constexpr decltype(auto) @\exposid{deref-move}@(I& it) { if constexpr (is_lvalue_reference_v) return std::move(*it); else From ca79655d51823665eeb4bd55af1c5185d1312274 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:06:25 -0800 Subject: [PATCH 47/54] LWG4455 Add missing constraint to basic-sender::get_completion_signatures definition Fixes NB US 215-356 (C++26 CD). --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 48c397ffd0..7d056a5386 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1998,7 +1998,7 @@ \indexlibrarymember{get_completion_signatures}{\exposid{basic-sender}}% \begin{itemdecl} template - template + template<@\exposconcept{decays-to}@<@\exposid{basic-sender}@> Sndr, class... Env> constexpr auto @\exposid{basic-sender}@::get_completion_signatures(); \end{itemdecl} From 641d222459b19f69afd50828d6b60626024f83b3 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:12:13 -0800 Subject: [PATCH 48/54] LWG4456 Decay Data and Child in make-sender Fixes NB US 211-351 (C++26 CD). --- source/exec.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 7d056a5386..9514c9e63d 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1691,7 +1691,8 @@ \item \tcode{(\libconcept{sender} \&\& ...)} \item% \tcode{\libconcept{dependent_sender} || \libconcept{sender_in}}, -where \tcode{Sndr} is \tcode{\exposid{basic-sender}} +where \tcode{Sndr} is +\tcode{\exposid{basic-sender}, decay_t...>} as defined below. \recommended From 1da2a2e04729e10070fa44fc7e9b8e95abbff7cb Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:14:56 -0800 Subject: [PATCH 49/54] LWG4459 Protect get_completion_signatures fold expression from overloaded commas Fixes NB US 214-355 (C++26 CD). --- source/exec.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 9514c9e63d..31cb836840 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -1977,7 +1977,7 @@ \effects Equivalent to: \begin{codeblock} -(get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(), ...); +((void)get_completion_signatures<@\exposid{child-type}@, @\exposid{FWD-ENV-T}@(Env)...>(), ...); \end{codeblock} \pnum From bba1f0e56a7984d3f921b302cadb92837ad05515 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:20:56 -0800 Subject: [PATCH 50/54] LWG4461 stop-when needs to evaluate unstoppable tokens Fixes US NB 226-345 (C++26 CD). --- source/exec.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/exec.tex b/source/exec.tex index 31cb836840..a2310e32e8 100644 --- a/source/exec.tex +++ b/source/exec.tex @@ -5168,7 +5168,8 @@ if \tcode{remove_cvref_t} models \libconcept{unstoppable_token} then \tcode{\exposid{stop-when}(\brk{}sndr, token)} is expression-equivalent to -\tcode{sndr}. +\tcode{(void)token, sndr}, +except that \tcode{token} and \tcode{sndr} are indeterminately sequenced. \item Otherwise, From 4769eb9f5d96d472fe801f38ea7bce382d676e66 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:23:13 -0800 Subject: [PATCH 51/54] LWG4462 Algorithm requirements don't describe semantics of s - i well Fixes NB US 154-252 (C++26 CD). --- source/algorithms.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 513939cf50..4f32bda3e9 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -233,7 +233,9 @@ \end{codeblock} For each iterator \tcode{i} and sentinel \tcode{s} produced from a range \tcode{r}, -the semantics of \tcode{s - i} has the same type, value, and value category +the semantics of \tcode{s - i} +are the same as those of an expression that +has the same type, value, and value category as \tcode{ranges::distance(i, s)}. \begin{note} The implementation can use \tcode{ranges::distance(r)} From e9a860ff5f3be72b7055148aa2e737130dcf4d73 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:25:58 -0800 Subject: [PATCH 52/54] LWG4463 Change wording to 'model' from 'subsumes' in [algorithms.parallel.user] Fixes NB US 155-253 (C++26 CD). --- source/algorithms.tex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 4f32bda3e9..17954239ab 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -381,7 +381,9 @@ \tcode{BinaryOperation1}, \tcode{BinaryOperation2}, \tcode{BinaryDivideOp}, or -constrained by a concept that subsumes \libconcept{regular_invocable} +constrained by a concept +whose semantic requirements include +that the type models \libconcept{regular_invocable} and the operators used by the analogous overloads to these parallel algorithms that are formed by an invocation with the specified default predicate or operation (where applicable) From 4b0f07229a8d4a17ae8b03c4daf47175694ba155 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:29:52 -0800 Subject: [PATCH 53/54] LWG4464 [alg.merge] Wording tweaks Fixes NB US 163-262 (C++26 CD). --- source/algorithms.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 17954239ab..a44466b78c 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -10107,12 +10107,12 @@ \tcode{proj2} be \tcode{identity\{\}}, for the overloads with no parameters by those names; \item - $E(\tcode{e1}, \tcode{e1})$ be \tcode{bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)))}; + $E$ be \tcode{bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)))}; \item $K$ be the smallest integer in \range{0}{last1 - first1} such that for the element \tcode{e1} in the position \tcode{first1 + $K$} there are at least $N - K$ elements \tcode{e2} - in \range{first2}{last2} for which $E(\tcode{e1}, \tcode{e1})$ holds, + in \range{first2}{last2} for which $E$ holds, and be equal to \tcode{last1 - first1} if no such integer exists. \begin{note} @@ -10137,7 +10137,7 @@ If \tcode{e1} is an element of \range{first1}{last1} and \tcode{e2} of \range{first2}{last2}, \tcode{e2} is copied into the output range before \tcode{e1} -if and only if $E(\tcode{e1}, \tcode{e1})$ is \tcode{true}. +if and only if $E$ is \tcode{true}. \pnum \returns From d3e367df108dc2fa1b37dc7521f200ae0e3cb9f6 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 3 Dec 2025 21:37:20 -0800 Subject: [PATCH 54/54] =?UTF-8?q?LWG4465=20=C2=A7[alg.partitions]=20Clarif?= =?UTF-8?q?y=20Returns:=20element?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes NB US 162-261 (C++26 CD). --- source/algorithms.tex | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index a44466b78c..b906bc2675 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -9965,19 +9965,19 @@ \effects For each iterator \tcode{i} in \range{first}{first + $N$}, copies \tcode{*i} to the output range \range{out_true}{last_true} -if \tcode{$E(\tcode{*i})$} is \tcode{true}, or +if $E(\tcode{*i})$ is \tcode{true}, or to the output range \range{out_false}{last_false} otherwise. \pnum \returns -Let \tcode{o1} be the iterator past the last copied element -in the output range \range{out_true}{last_true}, -and \tcode{o2} be the iterator past the last copied element -in the output range \range{out_false}{last_false}. +Let $Q$ be the number of elements copied +into the output range \range{out_true}{last_true}, +and $V$ be the number of elements copied +into the output range \range{out_false}{last_false}. Returns: \begin{itemize} -\item \tcode{\{o1, o2\}} for the overloads in namespace \tcode{std}. -\item \tcode{\{first + $N$, o1, o2\}} for the overloads in namespace \tcode{ranges}. +\item \tcode{\{out_true + $Q$, out_false + $V$\}} for the overloads in namespace \tcode{std}. +\item \tcode{\{first + $N$, out_true + $Q$, out_false + $V$\}} for the overloads in namespace \tcode{ranges}. \end{itemize} \pnum